From: Sven Eckelmann Date: Fri, 19 Nov 2021 16:12:00 +0000 (+0100) Subject: batman-adv: Refresh patches with quilt X-Git-Url: http://git.openwrt.org/%22https:/collectd.org//%22http:/www.crowdsec.net/%22/%22https:/collectd.org/%22http:/www.crowdsec.net/%22?a=commitdiff_plain;h=c8734df677192d09326514d0190af24469a9329e;p=feed%2Frouting.git batman-adv: Refresh patches with quilt The test builds are now requiring quilt refreshed patches instead of git patches. Otherwise the build check will not even try to build something. Signed-off-by: Sven Eckelmann --- diff --git a/batman-adv/patches/0001-Revert-batman-adv-convert-stream-like-files-from-non.patch b/batman-adv/patches/0001-Revert-batman-adv-convert-stream-like-files-from-non.patch index 201e327..74dd54e 100644 --- a/batman-adv/patches/0001-Revert-batman-adv-convert-stream-like-files-from-non.patch +++ b/batman-adv/patches/0001-Revert-batman-adv-convert-stream-like-files-from-non.patch @@ -7,11 +7,9 @@ API of Linux 5.2. This reverts commit 337ae19a00d4455cf84afa58abfb432f78c882b9. -diff --git a/compat-include/linux/fs.h b/compat-include/linux/fs.h -index 480722f04ba7ddefc837d5e55a340271e0814b14..c52e0e8e87584d106ab64ef2c522e6ac1ff6e796 100644 --- a/compat-include/linux/fs.h +++ b/compat-include/linux/fs.h -@@ -31,15 +31,4 @@ static inline struct dentry *batadv_file_dentry(const struct file *file) +@@ -31,15 +31,4 @@ static inline struct dentry *batadv_file #endif /* < KERNEL_VERSION(4, 6, 0) */ @@ -27,11 +25,9 @@ index 480722f04ba7ddefc837d5e55a340271e0814b14..c52e0e8e87584d106ab64ef2c522e6ac -#endif /* < KERNEL_VERSION(5, 2, 0) */ - #endif /* _NET_BATMAN_ADV_COMPAT_LINUX_FS_H_ */ -diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c -index 0a91c8661357d4ddbea1ba20dcd0df67b8ba5a97..de81b5ecad91afd8d684edbf781c70a3bae38c60 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c -@@ -65,7 +65,7 @@ static int batadv_socket_open(struct inode *inode, struct file *file) +@@ -65,7 +65,7 @@ static int batadv_socket_open(struct ino batadv_debugfs_deprecated(file, ""); @@ -40,11 +36,9 @@ index 0a91c8661357d4ddbea1ba20dcd0df67b8ba5a97..de81b5ecad91afd8d684edbf781c70a3 socket_client = kmalloc(sizeof(*socket_client), GFP_KERNEL); if (!socket_client) { -diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c -index f79ebd5b46e95b3b6de717c7ea1ecf44e5c96051..60ce11e16a905e790424a2d7aca81c1f945c1ec2 100644 --- a/net/batman-adv/log.c +++ b/net/batman-adv/log.c -@@ -90,7 +90,7 @@ static int batadv_log_open(struct inode *inode, struct file *file) +@@ -90,7 +90,7 @@ static int batadv_log_open(struct inode batadv_debugfs_deprecated(file, "Use tracepoint batadv:batadv_dbg instead\n"); diff --git a/batman-adv/patches/0001-batman-adv-Avoid-WARN_ON-timing-related-checks.patch b/batman-adv/patches/0001-batman-adv-Avoid-WARN_ON-timing-related-checks.patch deleted file mode 100644 index dda2034..0000000 --- a/batman-adv/patches/0001-batman-adv-Avoid-WARN_ON-timing-related-checks.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Sven Eckelmann -Date: Tue, 18 May 2021 21:00:27 +0200 -Subject: batman-adv: Avoid WARN_ON timing related checks - -The soft/batadv interface for a queued OGM can be changed during the time -the OGM was queued for transmission and when the OGM is actually -transmitted by the worker. - -But WARN_ON must be used to denote kernel bugs and not to print simple -warnings. A warning can simply be printed using pr_warn. - -Reported-by: Tetsuo Handa -Reported-by: syzbot+c0b807de416427ff3dd1@syzkaller.appspotmail.com -Fixes: 29b9256e6631 ("batman-adv: consider outgoing interface in OGM sending") -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/5061f9c502d7101912089d8f4a7866e0a926a49a - -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index bd4138ddf7e09a0020d9842d603dc98f21e225c7..2d398ac762aa612b6da2f64874bd07a6d84d5220 100644 ---- a/net/batman-adv/bat_iv_ogm.c -+++ b/net/batman-adv/bat_iv_ogm.c -@@ -373,8 +373,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet) - if (WARN_ON(!forw_packet->if_outgoing)) - return; - -- if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface)) -+ if (forw_packet->if_outgoing->soft_iface != soft_iface) { -+ pr_warn("%s: soft interface switch for queued OGM\n", __func__); - return; -+ } - - if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE) - return; diff --git a/batman-adv/patches/0002-Revert-batman-adv-compat-Drop-support-for-genl_ops-s.patch b/batman-adv/patches/0002-Revert-batman-adv-compat-Drop-support-for-genl_ops-s.patch index e3b7dec..38615f7 100644 --- a/batman-adv/patches/0002-Revert-batman-adv-compat-Drop-support-for-genl_ops-s.patch +++ b/batman-adv/patches/0002-Revert-batman-adv-compat-Drop-support-for-genl_ops-s.patch @@ -7,8 +7,6 @@ API of Linux 5.2. This reverts commit 1d30dbe3917d0d6fdb8ba473dfdd6265ac46670b. -diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h -index ee5b82288be97193c1a8e8340a2ea7e0c7ce112c..fbfdb733a3dd63c251def43cae416c7fe32cadab 100644 --- a/compat-include/net/genetlink.h +++ b/compat-include/net/genetlink.h @@ -42,6 +42,7 @@ enum genl_validate_flags { @@ -19,7 +17,7 @@ index ee5b82288be97193c1a8e8340a2ea7e0c7ce112c..fbfdb733a3dd63c251def43cae416c7f int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); -@@ -104,6 +105,7 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family) +@@ -104,6 +105,7 @@ static inline int batadv_genl_register_f for (i = 0; i < family->family.n_ops; i++) { ops[i].doit = family->ops[i].doit; diff --git a/batman-adv/patches/0003-Revert-batman-adv-genetlink-optionally-validate-stri.patch b/batman-adv/patches/0003-Revert-batman-adv-genetlink-optionally-validate-stri.patch index c383c69..f0e7cd1 100644 --- a/batman-adv/patches/0003-Revert-batman-adv-genetlink-optionally-validate-stri.patch +++ b/batman-adv/patches/0003-Revert-batman-adv-genetlink-optionally-validate-stri.patch @@ -7,11 +7,9 @@ API of Linux 5.2. This reverts commit 2ee47abaeb35ca62bb909830e10b0e973393b853. -diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h -index fbfdb733a3dd63c251def43cae416c7fe32cadab..7d17a705273650355f074788e9220fc4981b0db1 100644 --- a/compat-include/net/genetlink.h +++ b/compat-include/net/genetlink.h -@@ -33,25 +33,6 @@ void batadv_genl_dump_check_consistent(struct netlink_callback *cb, +@@ -33,25 +33,6 @@ void batadv_genl_dump_check_consistent(s #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0) @@ -55,7 +53,7 @@ index fbfdb733a3dd63c251def43cae416c7fe32cadab..7d17a705273650355f074788e9220fc4 static inline int batadv_genl_register_family(struct batadv_genl_family *family) { struct genl_ops *ops; -@@ -99,20 +82,12 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family) +@@ -99,20 +82,12 @@ static inline int batadv_genl_register_f family->family.n_mcgrps = family->n_mcgrps; family->family.module = family->module; @@ -78,7 +76,7 @@ index fbfdb733a3dd63c251def43cae416c7fe32cadab..7d17a705273650355f074788e9220fc4 family->family.ops = ops; family->copy_ops = ops; -@@ -120,17 +95,6 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family) +@@ -120,17 +95,6 @@ static inline int batadv_genl_register_f return genl_register_family(&family->family); } @@ -96,11 +94,9 @@ index fbfdb733a3dd63c251def43cae416c7fe32cadab..7d17a705273650355f074788e9220fc4 #define genl_register_family(family) \ batadv_genl_register_family((family)) -diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c -index a67720fad46ca496c932c0306e2f7ec4ed496fc9..e7907308b331ddc3e4917ff7d648bca27a65536b 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c -@@ -1343,34 +1343,29 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb, +@@ -1343,34 +1343,29 @@ static void batadv_post_doit(const struc static const struct genl_ops batadv_netlink_ops[] = { { .cmd = BATADV_CMD_GET_MESH, @@ -135,7 +131,7 @@ index a67720fad46ca496c932c0306e2f7ec4ed496fc9..e7907308b331ddc3e4917ff7d648bca2 /* can be retrieved by unprivileged users */ .dumpit = batadv_netlink_dump_hardif, .doit = batadv_netlink_get_hardif, -@@ -1379,68 +1374,57 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1379,68 +1374,57 @@ static const struct genl_ops batadv_netl }, { .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, @@ -204,7 +200,7 @@ index a67720fad46ca496c932c0306e2f7ec4ed496fc9..e7907308b331ddc3e4917ff7d648bca2 .flags = GENL_ADMIN_PERM, .doit = batadv_netlink_set_hardif, .internal_flags = BATADV_FLAG_NEED_MESH | -@@ -1448,7 +1432,6 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1448,7 +1432,6 @@ static const struct genl_ops batadv_netl }, { .cmd = BATADV_CMD_GET_VLAN, @@ -212,7 +208,7 @@ index a67720fad46ca496c932c0306e2f7ec4ed496fc9..e7907308b331ddc3e4917ff7d648bca2 /* can be retrieved by unprivileged users */ .doit = batadv_netlink_get_vlan, .internal_flags = BATADV_FLAG_NEED_MESH | -@@ -1456,7 +1439,6 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1456,7 +1439,6 @@ static const struct genl_ops batadv_netl }, { .cmd = BATADV_CMD_SET_VLAN, diff --git a/batman-adv/patches/0004-Revert-batman-adv-genetlink-make-policy-common-to-fa.patch b/batman-adv/patches/0004-Revert-batman-adv-genetlink-make-policy-common-to-fa.patch index a5814e7..f4de313 100644 --- a/batman-adv/patches/0004-Revert-batman-adv-genetlink-make-policy-common-to-fa.patch +++ b/batman-adv/patches/0004-Revert-batman-adv-genetlink-make-policy-common-to-fa.patch @@ -7,8 +7,6 @@ API of Linux 5.2. This reverts commit acfc9a214d01695d1676313ca80cfd2d9309f633. -diff --git a/compat-include/linux/cache.h b/compat-include/linux/cache.h -index 9ddda31232ed4b58efcb57dc2ee99ae82d09d6e2..efe440d11d04a1c3999649ba52058ad82e4d6bea 100644 --- a/compat-include/linux/cache.h +++ b/compat-include/linux/cache.h @@ -13,8 +13,12 @@ @@ -25,11 +23,9 @@ index 9ddda31232ed4b58efcb57dc2ee99ae82d09d6e2..efe440d11d04a1c3999649ba52058ad8 #define __ro_after_init #endif /* < KERNEL_VERSION(4, 6, 0) */ -diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h -index 7d17a705273650355f074788e9220fc4981b0db1..58fc24d7147a7f79c2db1976b36351d294f2aa4c 100644 --- a/compat-include/net/genetlink.h +++ b/compat-include/net/genetlink.h -@@ -30,92 +30,4 @@ void batadv_genl_dump_check_consistent(struct netlink_callback *cb, +@@ -30,92 +30,4 @@ void batadv_genl_dump_check_consistent(s #endif /* < KERNEL_VERSION(4, 15, 0) */ @@ -122,11 +118,9 @@ index 7d17a705273650355f074788e9220fc4981b0db1..58fc24d7147a7f79c2db1976b36351d2 -#endif /* < KERNEL_VERSION(5, 2, 0) */ - #endif /* _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ */ -diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c -index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf283d7686a3 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c -@@ -1344,29 +1344,34 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1344,29 +1344,34 @@ static const struct genl_ops batadv_netl { .cmd = BATADV_CMD_GET_MESH, /* can be retrieved by unprivileged users */ @@ -161,7 +155,7 @@ index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf28 .dumpit = batadv_netlink_dump_hardif, .doit = batadv_netlink_get_hardif, .internal_flags = BATADV_FLAG_NEED_MESH | -@@ -1375,57 +1380,68 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1375,57 +1380,68 @@ static const struct genl_ops batadv_netl { .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, .flags = GENL_ADMIN_PERM, @@ -230,7 +224,7 @@ index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf28 .doit = batadv_netlink_set_hardif, .internal_flags = BATADV_FLAG_NEED_MESH | BATADV_FLAG_NEED_HARDIF, -@@ -1433,6 +1449,7 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1433,6 +1449,7 @@ static const struct genl_ops batadv_netl { .cmd = BATADV_CMD_GET_VLAN, /* can be retrieved by unprivileged users */ @@ -238,7 +232,7 @@ index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf28 .doit = batadv_netlink_get_vlan, .internal_flags = BATADV_FLAG_NEED_MESH | BATADV_FLAG_NEED_VLAN, -@@ -1440,6 +1457,7 @@ static const struct genl_ops batadv_netlink_ops[] = { +@@ -1440,6 +1457,7 @@ static const struct genl_ops batadv_netl { .cmd = BATADV_CMD_SET_VLAN, .flags = GENL_ADMIN_PERM, @@ -246,7 +240,7 @@ index e7907308b331ddc3e4917ff7d648bca27a65536b..daf56933223d478399c63360203bcf28 .doit = batadv_netlink_set_vlan, .internal_flags = BATADV_FLAG_NEED_MESH | BATADV_FLAG_NEED_VLAN, -@@ -1451,7 +1469,6 @@ struct genl_family batadv_netlink_family __ro_after_init = { +@@ -1451,7 +1469,6 @@ struct genl_family batadv_netlink_family .name = BATADV_NL_NAME, .version = 1, .maxattr = BATADV_ATTR_MAX, diff --git a/batman-adv/patches/0005-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch b/batman-adv/patches/0005-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch index 2fc0e19..6c69557 100644 --- a/batman-adv/patches/0005-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch +++ b/batman-adv/patches/0005-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch @@ -24,11 +24,9 @@ Signed-off-by: Sven Eckelmann Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c92331e0df3c0c5645ee5a897eb018c5da5e4aa5 -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index bd4138ddf7e09a0020d9842d603dc98f21e225c7..240ed70912d6a014c0a48280741989133034396c 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c -@@ -2337,7 +2337,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1, +@@ -2337,7 +2337,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv return ret; } @@ -37,7 +35,7 @@ index bd4138ddf7e09a0020d9842d603dc98f21e225c7..240ed70912d6a014c0a4828074198913 { /* begin scheduling originator messages on that interface */ batadv_iv_ogm_schedule(hard_iface); -@@ -2683,8 +2683,8 @@ static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb, +@@ -2683,8 +2683,8 @@ unlock: static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .iface = { @@ -47,11 +45,9 @@ index bd4138ddf7e09a0020d9842d603dc98f21e225c7..240ed70912d6a014c0a4828074198913 .disable = batadv_iv_ogm_iface_disable, .update_mac = batadv_iv_ogm_iface_update_mac, .primary_set = batadv_iv_ogm_primary_iface_set, -diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -index 79d1731b83066c60f9aef958d2bc343233bce67a..3719cfd026f04093f5d86ffe1b41a41849b2af62 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c -@@ -795,6 +795,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, +@@ -795,6 +795,9 @@ int batadv_hardif_enable_interface(struc batadv_hardif_recalc_extra_skbroom(soft_iface); @@ -61,8 +57,6 @@ index 79d1731b83066c60f9aef958d2bc343233bce67a..3719cfd026f04093f5d86ffe1b41a418 out: return 0; -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index 74b644738a36bfe063eef6df016278b45a1a0256..e0b25104cbfa9f715df364658621c29faa7ad637 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -2129,6 +2129,9 @@ struct batadv_algo_iface_ops { diff --git a/batman-adv/patches/0006-batman-adv-Fix-netlink-dumping-of-all-mcast_flags-bu.patch b/batman-adv/patches/0006-batman-adv-Fix-netlink-dumping-of-all-mcast_flags-bu.patch index afc9db1..78a4bb3 100644 --- a/batman-adv/patches/0006-batman-adv-Fix-netlink-dumping-of-all-mcast_flags-bu.patch +++ b/batman-adv/patches/0006-batman-adv-Fix-netlink-dumping-of-all-mcast_flags-bu.patch @@ -14,11 +14,9 @@ Signed-off-by: Sven Eckelmann Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d1de7f7aa316d6f7b3268f61afa88f5d2c1a5db5 -diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c -index ec54e236e345432496df8f55b2e00fbad92f3444..50fe9dfb088b60a911756c8c22cac1db6ef10ca4 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c -@@ -1653,7 +1653,7 @@ __batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, +@@ -1653,7 +1653,7 @@ __batadv_mcast_flags_dump(struct sk_buff while (bucket_tmp < hash->size) { if (batadv_mcast_flags_dump_bucket(msg, portid, cb, hash, diff --git a/batman-adv/patches/0007-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch b/batman-adv/patches/0007-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch index 0a79f4b..f81cf61 100644 --- a/batman-adv/patches/0007-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch +++ b/batman-adv/patches/0007-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch @@ -43,11 +43,9 @@ Signed-off-by: Sven Eckelmann Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b470b8a2b9ef4ce68d6e95febd3a0574be1ac14 -diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c -index daf56933223d478399c63360203bcf283d7686a3..e1978bc52a700e77ff881136c05ccb934f3b851d 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c -@@ -164,7 +164,7 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype) +@@ -164,7 +164,7 @@ batadv_netlink_get_ifindex(const struct { struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype); diff --git a/batman-adv/patches/0008-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch b/batman-adv/patches/0008-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch index f33fdc3..e5b1383 100644 --- a/batman-adv/patches/0008-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch +++ b/batman-adv/patches/0008-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch @@ -21,11 +21,9 @@ Acked-by: Antonio Quartulli Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/07b6051ebcfaa7ea89b4f278eca2ff4070d29e56 -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index 240ed70912d6a014c0a48280741989133034396c..d78938e3e0085d9cff138b805148a0e77de3f654 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c -@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv) +@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, cons * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached * @buff_pos: current position in the skb * @packet_len: total length of the skb @@ -54,7 +52,7 @@ index 240ed70912d6a014c0a48280741989133034396c..d78938e3e0085d9cff138b805148a0e7 return (next_buff_pos <= packet_len) && (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); -@@ -315,7 +321,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, +@@ -315,7 +321,7 @@ static void batadv_iv_ogm_send_to_if(str /* adjust all flags and log packets */ while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, @@ -63,7 +61,7 @@ index 240ed70912d6a014c0a48280741989133034396c..d78938e3e0085d9cff138b805148a0e7 /* we might have aggregated direct link packets with an * ordinary base packet */ -@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, +@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct /* unpack the aggregated packets and process them one by one */ while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb), diff --git a/batman-adv/patches/0009-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch b/batman-adv/patches/0009-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch index e53ea2f..2921994 100644 --- a/batman-adv/patches/0009-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch +++ b/batman-adv/patches/0009-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch @@ -18,11 +18,9 @@ Signed-off-by: Sven Eckelmann Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/18f77da3761c5550f42a2d131f0fe5cac62e022d -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index fad95ef64e01a9670ed66f9a81658718a14fc716..bc06e3cdfa84f63cc003867d4453a88249d3fb18 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c -@@ -631,17 +631,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv, +@@ -631,17 +631,23 @@ batadv_v_ogm_process_per_outif(struct ba * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated * @buff_pos: current position in the skb * @packet_len: total length of the skb @@ -51,7 +49,7 @@ index fad95ef64e01a9670ed66f9a81658718a14fc716..bc06e3cdfa84f63cc003867d4453a882 return (next_buff_pos <= packet_len) && (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); -@@ -818,7 +824,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb, +@@ -818,7 +824,7 @@ int batadv_v_ogm_packet_recv(struct sk_b ogm_packet = (struct batadv_ogm2_packet *)skb->data; while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb), diff --git a/batman-adv/patches/0010-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch b/batman-adv/patches/0010-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch index dd20d53..420a4e6 100644 --- a/batman-adv/patches/0010-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch +++ b/batman-adv/patches/0010-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch @@ -19,8 +19,6 @@ Signed-off-by: Sven Eckelmann Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/14ee24576213ff02272b7f8d975c7c61d5448aa2 -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6663da7f3 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -21,6 +21,7 @@ @@ -31,7 +29,7 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 #include #include #include -@@ -116,14 +117,12 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb, +@@ -116,14 +117,12 @@ static void batadv_v_ogm_send_to_if(stru } /** @@ -49,7 +47,7 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 struct batadv_ogm2_packet *ogm_packet; struct sk_buff *skb, *skb_tmp; unsigned char *ogm_buff; -@@ -131,8 +130,7 @@ static void batadv_v_ogm_send(struct work_struct *work) +@@ -131,8 +130,7 @@ static void batadv_v_ogm_send(struct wor u16 tvlv_len = 0; int ret; @@ -59,11 +57,10 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) goto out; -@@ -223,6 +221,22 @@ static void batadv_v_ogm_send(struct work_struct *work) - return; +@@ -224,6 +222,22 @@ out: } -+/** + /** + * batadv_v_ogm_send() - periodic worker broadcasting the own OGM + * @work: work queue item + */ @@ -79,10 +76,11 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 + rtnl_unlock(); +} + - /** ++/** * batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V * @hard_iface: the interface to prepare -@@ -249,6 +263,8 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) + * +@@ -249,6 +263,8 @@ void batadv_v_ogm_primary_iface_set(stru struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); struct batadv_ogm2_packet *ogm_packet; @@ -91,7 +89,7 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 if (!bat_priv->bat_v.ogm_buff) return; -@@ -857,6 +873,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) +@@ -857,6 +873,8 @@ int batadv_v_ogm_init(struct batadv_priv unsigned char *ogm_buff; u32 random_seqno; @@ -100,8 +98,6 @@ index bc06e3cdfa84f63cc003867d4453a88249d3fb18..034bdc5e31e7b1b6f12c06da9977b3b6 bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN; ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC); if (!ogm_buff) -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index e0b25104cbfa9f715df364658621c29faa7ad637..f298e9a04986faf40db04ece14180b7f43b5a7b7 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1477,10 +1477,10 @@ struct batadv_softif_vlan { diff --git a/batman-adv/patches/0010-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch b/batman-adv/patches/0010-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch deleted file mode 100644 index 4288c4f..0000000 --- a/batman-adv/patches/0010-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Tetsuo Handa -Date: Mon, 5 Apr 2021 19:16:50 +0900 -Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field - -KMSAN found uninitialized value at batadv_tt_prepare_tvlv_local_data() -[1], for commit ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16 -in TT code") inserted 'reserved' field into "struct batadv_tvlv_tt_data" -and commit 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN -specific") moved that field to "struct batadv_tvlv_tt_vlan_data" but left -that field uninitialized. - -[1] https://syzkaller.appspot.com/bug?id=07f3e6dba96f0eb3cabab986adcd8a58b9bdbe9d - -Reported-by: syzbot -Tested-by: syzbot -Signed-off-by: Tetsuo Handa -Fixes: c5e7a06a2961 ("batman-adv: use CRC32C instead of CRC16 in TT code") -Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific") -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fe8bf38f47a0c1a0e53c487228e3f5a44c86939f - -diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c -index 8a482c5ec67bb22167bca02b4181252045e3b605..c5271ea4dc8321fadc75fca7790b1382102dbb5a 100644 ---- a/net/batman-adv/translation-table.c -+++ b/net/batman-adv/translation-table.c -@@ -891,6 +891,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node, - hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { - tt_vlan->vid = htons(vlan->vid); - tt_vlan->crc = htonl(vlan->tt.crc); -+ tt_vlan->reserved = 0; - - tt_vlan++; - } -@@ -974,6 +975,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, - - tt_vlan->vid = htons(vlan->vid); - tt_vlan->crc = htonl(vlan->tt.crc); -+ tt_vlan->reserved = 0; - - tt_vlan++; - } diff --git a/batman-adv/patches/0011-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch b/batman-adv/patches/0011-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch deleted file mode 100644 index b0718d1..0000000 --- a/batman-adv/patches/0011-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch +++ /dev/null @@ -1,136 +0,0 @@ -From: Sven Eckelmann -Date: Thu, 3 Oct 2019 17:02:01 +0200 -Subject: batman-adv: Avoid free/alloc race when handling OGM buffer - -Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM -packet buffer which is initialized using data from the RTNL lock protected -netdevice notifier and other rtnetlink related hooks. It is sent regularly -via various slave interfaces of the batadv virtual interface and in this -process also modified (realloced) to integrate additional state information -via TVLV containers. - -It must be avoided that the worker item is executed without a common lock -with the netdevice notifier/rtnetlink helpers. Otherwise it can either -happen that half modified/freed data is sent out or functions modifying the -OGM buffer try to access already freed memory regions. - -Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com -Fixes: ea6f8d42a595 ("batman-adv: move /proc interface handling to /sys") -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b8ceef26c697d0c8319748428944c3339a498dc - -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index d78938e3e0085d9cff138b805148a0e77de3f654..e20c3813182c422a52f58178f05010869c5ebe66 100644 ---- a/net/batman-adv/bat_iv_ogm.c -+++ b/net/batman-adv/bat_iv_ogm.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -193,6 +194,8 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) - unsigned char *ogm_buff; - u32 random_seqno; - -+ ASSERT_RTNL(); -+ - /* randomize initial seqno to avoid collision */ - get_random_bytes(&random_seqno, sizeof(random_seqno)); - atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); -@@ -217,6 +220,8 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) - - static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) - { -+ ASSERT_RTNL(); -+ - kfree(hard_iface->bat_iv.ogm_buff); - hard_iface->bat_iv.ogm_buff = NULL; - } -@@ -226,6 +231,8 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) - struct batadv_ogm_packet *batadv_ogm_packet; - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; - -+ ASSERT_RTNL(); -+ - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; - ether_addr_copy(batadv_ogm_packet->orig, - hard_iface->net_dev->dev_addr); -@@ -239,6 +246,8 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) - struct batadv_ogm_packet *batadv_ogm_packet; - unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; - -+ ASSERT_RTNL(); -+ - batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; - batadv_ogm_packet->ttl = BATADV_TTL; - } -@@ -753,6 +762,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) - u16 tvlv_len = 0; - unsigned long send_time; - -+ ASSERT_RTNL(); -+ - if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || - hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) - return; -@@ -1643,16 +1654,12 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, - batadv_orig_node_put(orig_node); - } - --static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) -+static void -+batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet) - { -- struct delayed_work *delayed_work; -- struct batadv_forw_packet *forw_packet; - struct batadv_priv *bat_priv; - bool dropped = false; - -- delayed_work = to_delayed_work(work); -- forw_packet = container_of(delayed_work, struct batadv_forw_packet, -- delayed_work); - bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { -@@ -1681,6 +1688,20 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) - batadv_forw_packet_free(forw_packet, dropped); - } - -+static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work; -+ struct batadv_forw_packet *forw_packet; -+ -+ delayed_work = to_delayed_work(work); -+ forw_packet = container_of(delayed_work, struct batadv_forw_packet, -+ delayed_work); -+ -+ rtnl_lock(); -+ batadv_iv_send_outstanding_forw_packet(forw_packet); -+ rtnl_unlock(); -+} -+ - static int batadv_iv_ogm_receive(struct sk_buff *skb, - struct batadv_hard_iface *if_incoming) - { -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index f298e9a04986faf40db04ece14180b7f43b5a7b7..f3084b005ed641d8ab8910df542762bc7dff450a 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -71,10 +71,10 @@ enum batadv_dhcp_recipient { - * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data - */ - struct batadv_hard_iface_bat_iv { -- /** @ogm_buff: buffer holding the OGM packet */ -+ /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ - unsigned char *ogm_buff; - -- /** @ogm_buff_len: length of the OGM packet buffer */ -+ /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ - int ogm_buff_len; - - /** @ogm_seqno: OGM sequence number - used to identify each OGM */ diff --git a/batman-adv/patches/0011-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch b/batman-adv/patches/0011-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch new file mode 100644 index 0000000..a612310 --- /dev/null +++ b/batman-adv/patches/0011-batman-adv-initialize-struct-batadv_tvlv_tt_vlan_dat.patch @@ -0,0 +1,39 @@ +From: Tetsuo Handa +Date: Mon, 5 Apr 2021 19:16:50 +0900 +Subject: batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field + +KMSAN found uninitialized value at batadv_tt_prepare_tvlv_local_data() +[1], for commit ced72933a5e8ab52 ("batman-adv: use CRC32C instead of CRC16 +in TT code") inserted 'reserved' field into "struct batadv_tvlv_tt_data" +and commit 7ea7b4a142758dea ("batman-adv: make the TT CRC logic VLAN +specific") moved that field to "struct batadv_tvlv_tt_vlan_data" but left +that field uninitialized. + +[1] https://syzkaller.appspot.com/bug?id=07f3e6dba96f0eb3cabab986adcd8a58b9bdbe9d + +Reported-by: syzbot +Tested-by: syzbot +Signed-off-by: Tetsuo Handa +Fixes: c5e7a06a2961 ("batman-adv: use CRC32C instead of CRC16 in TT code") +Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific") +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fe8bf38f47a0c1a0e53c487228e3f5a44c86939f + +--- a/net/batman-adv/translation-table.c ++++ b/net/batman-adv/translation-table.c +@@ -891,6 +891,7 @@ batadv_tt_prepare_tvlv_global_data(struc + hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) { + tt_vlan->vid = htons(vlan->vid); + tt_vlan->crc = htonl(vlan->tt.crc); ++ tt_vlan->reserved = 0; + + tt_vlan++; + } +@@ -974,6 +975,7 @@ batadv_tt_prepare_tvlv_local_data(struct + + tt_vlan->vid = htons(vlan->vid); + tt_vlan->crc = htonl(vlan->tt.crc); ++ tt_vlan->reserved = 0; + + tt_vlan++; + } diff --git a/batman-adv/patches/0012-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch b/batman-adv/patches/0012-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch new file mode 100644 index 0000000..ffcefde --- /dev/null +++ b/batman-adv/patches/0012-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch @@ -0,0 +1,132 @@ +From: Sven Eckelmann +Date: Thu, 3 Oct 2019 17:02:01 +0200 +Subject: batman-adv: Avoid free/alloc race when handling OGM buffer + +Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM +packet buffer which is initialized using data from the RTNL lock protected +netdevice notifier and other rtnetlink related hooks. It is sent regularly +via various slave interfaces of the batadv virtual interface and in this +process also modified (realloced) to integrate additional state information +via TVLV containers. + +It must be avoided that the worker item is executed without a common lock +with the netdevice notifier/rtnetlink helpers. Otherwise it can either +happen that half modified/freed data is sent out or functions modifying the +OGM buffer try to access already freed memory regions. + +Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com +Fixes: ea6f8d42a595 ("batman-adv: move /proc interface handling to /sys") +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b8ceef26c697d0c8319748428944c3339a498dc + +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -193,6 +194,8 @@ static int batadv_iv_ogm_iface_enable(st + unsigned char *ogm_buff; + u32 random_seqno; + ++ ASSERT_RTNL(); ++ + /* randomize initial seqno to avoid collision */ + get_random_bytes(&random_seqno, sizeof(random_seqno)); + atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno); +@@ -217,6 +220,8 @@ static int batadv_iv_ogm_iface_enable(st + + static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) + { ++ ASSERT_RTNL(); ++ + kfree(hard_iface->bat_iv.ogm_buff); + hard_iface->bat_iv.ogm_buff = NULL; + } +@@ -226,6 +231,8 @@ static void batadv_iv_ogm_iface_update_m + struct batadv_ogm_packet *batadv_ogm_packet; + unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; + ++ ASSERT_RTNL(); ++ + batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; + ether_addr_copy(batadv_ogm_packet->orig, + hard_iface->net_dev->dev_addr); +@@ -239,6 +246,8 @@ batadv_iv_ogm_primary_iface_set(struct b + struct batadv_ogm_packet *batadv_ogm_packet; + unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; + ++ ASSERT_RTNL(); ++ + batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; + batadv_ogm_packet->ttl = BATADV_TTL; + } +@@ -753,6 +762,8 @@ static void batadv_iv_ogm_schedule(struc + u16 tvlv_len = 0; + unsigned long send_time; + ++ ASSERT_RTNL(); ++ + if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || + hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) + return; +@@ -1643,16 +1654,12 @@ static void batadv_iv_ogm_process(const + batadv_orig_node_put(orig_node); + } + +-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) ++static void ++batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet) + { +- struct delayed_work *delayed_work; +- struct batadv_forw_packet *forw_packet; + struct batadv_priv *bat_priv; + bool dropped = false; + +- delayed_work = to_delayed_work(work); +- forw_packet = container_of(delayed_work, struct batadv_forw_packet, +- delayed_work); + bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); + + if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { +@@ -1681,6 +1688,20 @@ out: + batadv_forw_packet_free(forw_packet, dropped); + } + ++static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) ++{ ++ struct delayed_work *delayed_work; ++ struct batadv_forw_packet *forw_packet; ++ ++ delayed_work = to_delayed_work(work); ++ forw_packet = container_of(delayed_work, struct batadv_forw_packet, ++ delayed_work); ++ ++ rtnl_lock(); ++ batadv_iv_send_outstanding_forw_packet(forw_packet); ++ rtnl_unlock(); ++} ++ + static int batadv_iv_ogm_receive(struct sk_buff *skb, + struct batadv_hard_iface *if_incoming) + { +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -71,10 +71,10 @@ enum batadv_dhcp_recipient { + * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data + */ + struct batadv_hard_iface_bat_iv { +- /** @ogm_buff: buffer holding the OGM packet */ ++ /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ + unsigned char *ogm_buff; + +- /** @ogm_buff_len: length of the OGM packet buffer */ ++ /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ + int ogm_buff_len; + + /** @ogm_seqno: OGM sequence number - used to identify each OGM */ diff --git a/batman-adv/patches/0012-batman-adv-Introduce-own-OGM2-buffer-mutex.patch b/batman-adv/patches/0012-batman-adv-Introduce-own-OGM2-buffer-mutex.patch deleted file mode 100644 index 49d8e25..0000000 --- a/batman-adv/patches/0012-batman-adv-Introduce-own-OGM2-buffer-mutex.patch +++ /dev/null @@ -1,138 +0,0 @@ -From: Sven Eckelmann -Date: Sun, 13 Oct 2019 21:03:06 +0200 -Subject: batman-adv: Introduce own OGM2 buffer mutex - -Only a single function is currently automatically locked by the rtnl_lock -because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard -interfaces on which it will be transmitted. A private mutex can be used -instead to avoid unnecessary delays which would have been introduced by the -global lock. - -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821 - -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index 034bdc5e31e7b1b6f12c06da9977b3b6663da7f3..74452e9385b1a6e81be64af259dfc371cd3e9655 100644 ---- a/net/batman-adv/bat_v_ogm.c -+++ b/net/batman-adv/bat_v_ogm.c -@@ -17,11 +17,12 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include - #include --#include - #include - #include - #include -@@ -130,7 +131,7 @@ static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv) - u16 tvlv_len = 0; - int ret; - -- ASSERT_RTNL(); -+ lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); - - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) - goto out; -@@ -230,11 +231,12 @@ static void batadv_v_ogm_send(struct work_struct *work) - struct batadv_priv_bat_v *bat_v; - struct batadv_priv *bat_priv; - -- rtnl_lock(); - bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); - bat_priv = container_of(bat_v, struct batadv_priv, bat_v); -+ -+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); - batadv_v_ogm_send_softif(bat_priv); -- rtnl_unlock(); -+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); - } - - /** -@@ -263,13 +265,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) - struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); - struct batadv_ogm2_packet *ogm_packet; - -- ASSERT_RTNL(); -- -+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); - if (!bat_priv->bat_v.ogm_buff) -- return; -+ goto unlock; - - ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff; - ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr); -+ -+unlock: -+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); - } - - /** -@@ -873,8 +877,6 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) - unsigned char *ogm_buff; - u32 random_seqno; - -- ASSERT_RTNL(); -- - bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN; - ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC); - if (!ogm_buff) -@@ -893,6 +895,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv) - atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno); - INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send); - -+ mutex_init(&bat_priv->bat_v.ogm_buff_mutex); -+ - return 0; - } - -@@ -904,7 +908,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv) - { - cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq); - -+ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); -+ - kfree(bat_priv->bat_v.ogm_buff); - bat_priv->bat_v.ogm_buff = NULL; - bat_priv->bat_v.ogm_buff_len = 0; -+ -+ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); - } -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index f3084b005ed641d8ab8910df542762bc7dff450a..09f44bac693fcb3dc13c33319f4928a472a14b2e 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include /* for linux/wait.h */ -@@ -1477,15 +1478,18 @@ struct batadv_softif_vlan { - * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data - */ - struct batadv_priv_bat_v { -- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ -+ /** @ogm_buff: buffer holding the OGM packet */ - unsigned char *ogm_buff; - -- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ -+ /** @ogm_buff_len: length of the OGM packet buffer */ - int ogm_buff_len; - - /** @ogm_seqno: OGM sequence number - used to identify each OGM */ - atomic_t ogm_seqno; - -+ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ -+ struct mutex ogm_buff_mutex; -+ - /** @ogm_wq: workqueue used to schedule OGM transmissions */ - struct delayed_work ogm_wq; - }; diff --git a/batman-adv/patches/0013-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch b/batman-adv/patches/0013-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch deleted file mode 100644 index bd187c7..0000000 --- a/batman-adv/patches/0013-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch +++ /dev/null @@ -1,263 +0,0 @@ -From: Sven Eckelmann -Date: Sun, 13 Oct 2019 21:03:07 +0200 -Subject: batman-adv: Avoid OGM workqueue synchronous cancel deadlock - -batadv_forw_packet_list_free can be called when an interface is being -disabled. Under this circumstance, the rntl_lock will be held and while it -calls cancel_delayed_work_sync. - -cancel_delayed_work_sync will stop the execution of the current context -when the work item is currently processed. It can now happen that the -cancel_delayed_work_sync was called when rtnl_lock was already called in -batadv_iv_send_outstanding_bat_ogm_packet or when it was in the process of -calling it. In this case, batadv_iv_send_outstanding_bat_ogm_packet waits -for the lock and cancel_delayed_work_sync (which holds the rtnl_lock) is -waiting for batadv_iv_send_outstanding_bat_ogm_packet to finish. - -This can only be avoided by not using (conflicting) blocking locks while -cancel_delayed_work_sync is called. It also has the benefit that the -ogm scheduling functionality can avoid unnecessary delays which can be -introduced by a global lock. - -Fixes: 9b8ceef26c69 ("batman-adv: Avoid free/alloc race when handling OGM buffer") -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d3be478f1aa27b47f61c4a62e18eb063d47c9168 - -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index e20c3813182c422a52f58178f05010869c5ebe66..5b0b20e6da956b4333b118bce1c09c5acef6d66f 100644 ---- a/net/batman-adv/bat_iv_ogm.c -+++ b/net/batman-adv/bat_iv_ogm.c -@@ -22,6 +22,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -29,7 +31,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -194,7 +195,7 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) - unsigned char *ogm_buff; - u32 random_seqno; - -- ASSERT_RTNL(); -+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); - - /* randomize initial seqno to avoid collision */ - get_random_bytes(&random_seqno, sizeof(random_seqno)); -@@ -202,8 +203,10 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) - - hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; - ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); -- if (!ogm_buff) -+ if (!ogm_buff) { -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); - return -ENOMEM; -+ } - - hard_iface->bat_iv.ogm_buff = ogm_buff; - -@@ -215,41 +218,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface) - batadv_ogm_packet->reserved = 0; - batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; - -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); -+ - return 0; - } - - static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) - { -- ASSERT_RTNL(); -+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); - - kfree(hard_iface->bat_iv.ogm_buff); - hard_iface->bat_iv.ogm_buff = NULL; -+ -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); - } - - static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) - { - struct batadv_ogm_packet *batadv_ogm_packet; -- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; -+ void *ogm_buff; - -- ASSERT_RTNL(); -+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); - -- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; -+ ogm_buff = hard_iface->bat_iv.ogm_buff; -+ if (!ogm_buff) -+ goto unlock; -+ -+ batadv_ogm_packet = ogm_buff; - ether_addr_copy(batadv_ogm_packet->orig, - hard_iface->net_dev->dev_addr); - ether_addr_copy(batadv_ogm_packet->prev_sender, - hard_iface->net_dev->dev_addr); -+ -+unlock: -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); - } - - static void - batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) - { - struct batadv_ogm_packet *batadv_ogm_packet; -- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; -+ void *ogm_buff; - -- ASSERT_RTNL(); -+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); - -- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; -+ ogm_buff = hard_iface->bat_iv.ogm_buff; -+ if (!ogm_buff) -+ goto unlock; -+ -+ batadv_ogm_packet = ogm_buff; - batadv_ogm_packet->ttl = BATADV_TTL; -+ -+unlock: -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); - } - - /* when do we schedule our own ogm to be sent */ -@@ -751,7 +772,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) - } - } - --static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) -+/** -+ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer -+ * @hard_iface: interface whose ogm buffer should be transmitted -+ */ -+static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) - { - struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); - unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; -@@ -762,11 +787,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) - u16 tvlv_len = 0; - unsigned long send_time; - -- ASSERT_RTNL(); -- -- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || -- hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) -- return; -+ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); - - /* the interface gets activated here to avoid race conditions between - * the moment of activating the interface in -@@ -834,6 +855,17 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) - batadv_hardif_put(primary_if); - } - -+static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) -+{ -+ if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || -+ hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) -+ return; -+ -+ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); -+ batadv_iv_ogm_schedule_buff(hard_iface); -+ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); -+} -+ - /** - * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface - * @orig_node: originator which reproadcasted the OGMs directly -@@ -1654,12 +1686,16 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, - batadv_orig_node_put(orig_node); - } - --static void --batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet) -+static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) - { -+ struct delayed_work *delayed_work; -+ struct batadv_forw_packet *forw_packet; - struct batadv_priv *bat_priv; - bool dropped = false; - -+ delayed_work = to_delayed_work(work); -+ forw_packet = container_of(delayed_work, struct batadv_forw_packet, -+ delayed_work); - bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { -@@ -1688,20 +1724,6 @@ batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet) - batadv_forw_packet_free(forw_packet, dropped); - } - --static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) --{ -- struct delayed_work *delayed_work; -- struct batadv_forw_packet *forw_packet; -- -- delayed_work = to_delayed_work(work); -- forw_packet = container_of(delayed_work, struct batadv_forw_packet, -- delayed_work); -- -- rtnl_lock(); -- batadv_iv_send_outstanding_forw_packet(forw_packet); -- rtnl_unlock(); --} -- - static int batadv_iv_ogm_receive(struct sk_buff *skb, - struct batadv_hard_iface *if_incoming) - { -diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -index 3719cfd026f04093f5d86ffe1b41a41849b2af62..62b926dd4aaeffd82da83654c8e568de2c3714fb 100644 ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -930,6 +931,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) - INIT_LIST_HEAD(&hard_iface->list); - INIT_HLIST_HEAD(&hard_iface->neigh_list); - -+ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); - spin_lock_init(&hard_iface->neigh_list_lock); - kref_init(&hard_iface->refcount); - -diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -index 09f44bac693fcb3dc13c33319f4928a472a14b2e..c0ded822517b94333451deb9c0ff4037744b1fd9 100644 ---- a/net/batman-adv/types.h -+++ b/net/batman-adv/types.h -@@ -72,14 +72,17 @@ enum batadv_dhcp_recipient { - * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data - */ - struct batadv_hard_iface_bat_iv { -- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ -+ /** @ogm_buff: buffer holding the OGM packet */ - unsigned char *ogm_buff; - -- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ -+ /** @ogm_buff_len: length of the OGM packet buffer */ - int ogm_buff_len; - - /** @ogm_seqno: OGM sequence number - used to identify each OGM */ - atomic_t ogm_seqno; -+ -+ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ -+ struct mutex ogm_buff_mutex; - }; - - /** diff --git a/batman-adv/patches/0013-batman-adv-Introduce-own-OGM2-buffer-mutex.patch b/batman-adv/patches/0013-batman-adv-Introduce-own-OGM2-buffer-mutex.patch new file mode 100644 index 0000000..c938507 --- /dev/null +++ b/batman-adv/patches/0013-batman-adv-Introduce-own-OGM2-buffer-mutex.patch @@ -0,0 +1,134 @@ +From: Sven Eckelmann +Date: Sun, 13 Oct 2019 21:03:06 +0200 +Subject: batman-adv: Introduce own OGM2 buffer mutex + +Only a single function is currently automatically locked by the rtnl_lock +because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard +interfaces on which it will be transmitted. A private mutex can be used +instead to avoid unnecessary delays which would have been introduced by the +global lock. + +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821 + +--- a/net/batman-adv/bat_v_ogm.c ++++ b/net/batman-adv/bat_v_ogm.c +@@ -17,11 +17,12 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include + #include +-#include + #include + #include + #include +@@ -130,7 +131,7 @@ static void batadv_v_ogm_send_softif(str + u16 tvlv_len = 0; + int ret; + +- ASSERT_RTNL(); ++ lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); + + if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) + goto out; +@@ -230,11 +231,12 @@ static void batadv_v_ogm_send(struct wor + struct batadv_priv_bat_v *bat_v; + struct batadv_priv *bat_priv; + +- rtnl_lock(); + bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work); + bat_priv = container_of(bat_v, struct batadv_priv, bat_v); ++ ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); + batadv_v_ogm_send_softif(bat_priv); +- rtnl_unlock(); ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); + } + + /** +@@ -263,13 +265,15 @@ void batadv_v_ogm_primary_iface_set(stru + struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface); + struct batadv_ogm2_packet *ogm_packet; + +- ASSERT_RTNL(); +- ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); + if (!bat_priv->bat_v.ogm_buff) +- return; ++ goto unlock; + + ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff; + ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr); ++ ++unlock: ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); + } + + /** +@@ -873,8 +877,6 @@ int batadv_v_ogm_init(struct batadv_priv + unsigned char *ogm_buff; + u32 random_seqno; + +- ASSERT_RTNL(); +- + bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN; + ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC); + if (!ogm_buff) +@@ -893,6 +895,8 @@ int batadv_v_ogm_init(struct batadv_priv + atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno); + INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send); + ++ mutex_init(&bat_priv->bat_v.ogm_buff_mutex); ++ + return 0; + } + +@@ -904,7 +908,11 @@ void batadv_v_ogm_free(struct batadv_pri + { + cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq); + ++ mutex_lock(&bat_priv->bat_v.ogm_buff_mutex); ++ + kfree(bat_priv->bat_v.ogm_buff); + bat_priv->bat_v.ogm_buff = NULL; + bat_priv->bat_v.ogm_buff_len = 0; ++ ++ mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex); + } +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include /* for linux/wait.h */ +@@ -1477,15 +1478,18 @@ struct batadv_softif_vlan { + * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data + */ + struct batadv_priv_bat_v { +- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ ++ /** @ogm_buff: buffer holding the OGM packet */ + unsigned char *ogm_buff; + +- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ ++ /** @ogm_buff_len: length of the OGM packet buffer */ + int ogm_buff_len; + + /** @ogm_seqno: OGM sequence number - used to identify each OGM */ + atomic_t ogm_seqno; + ++ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ ++ struct mutex ogm_buff_mutex; ++ + /** @ogm_wq: workqueue used to schedule OGM transmissions */ + struct delayed_work ogm_wq; + }; diff --git a/batman-adv/patches/0014-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch b/batman-adv/patches/0014-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch new file mode 100644 index 0000000..0216ca8 --- /dev/null +++ b/batman-adv/patches/0014-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch @@ -0,0 +1,257 @@ +From: Sven Eckelmann +Date: Sun, 13 Oct 2019 21:03:07 +0200 +Subject: batman-adv: Avoid OGM workqueue synchronous cancel deadlock + +batadv_forw_packet_list_free can be called when an interface is being +disabled. Under this circumstance, the rntl_lock will be held and while it +calls cancel_delayed_work_sync. + +cancel_delayed_work_sync will stop the execution of the current context +when the work item is currently processed. It can now happen that the +cancel_delayed_work_sync was called when rtnl_lock was already called in +batadv_iv_send_outstanding_bat_ogm_packet or when it was in the process of +calling it. In this case, batadv_iv_send_outstanding_bat_ogm_packet waits +for the lock and cancel_delayed_work_sync (which holds the rtnl_lock) is +waiting for batadv_iv_send_outstanding_bat_ogm_packet to finish. + +This can only be avoided by not using (conflicting) blocking locks while +cancel_delayed_work_sync is called. It also has the benefit that the +ogm scheduling functionality can avoid unnecessary delays which can be +introduced by a global lock. + +Fixes: 9b8ceef26c69 ("batman-adv: Avoid free/alloc race when handling OGM buffer") +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d3be478f1aa27b47f61c4a62e18eb063d47c9168 + +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -22,6 +22,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -29,7 +31,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -194,7 +195,7 @@ static int batadv_iv_ogm_iface_enable(st + unsigned char *ogm_buff; + u32 random_seqno; + +- ASSERT_RTNL(); ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + + /* randomize initial seqno to avoid collision */ + get_random_bytes(&random_seqno, sizeof(random_seqno)); +@@ -202,8 +203,10 @@ static int batadv_iv_ogm_iface_enable(st + + hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN; + ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC); +- if (!ogm_buff) ++ if (!ogm_buff) { ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + return -ENOMEM; ++ } + + hard_iface->bat_iv.ogm_buff = ogm_buff; + +@@ -215,41 +218,59 @@ static int batadv_iv_ogm_iface_enable(st + batadv_ogm_packet->reserved = 0; + batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE; + ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++ + return 0; + } + + static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface) + { +- ASSERT_RTNL(); ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + + kfree(hard_iface->bat_iv.ogm_buff); + hard_iface->bat_iv.ogm_buff = NULL; ++ ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- ASSERT_RTNL(); ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + ether_addr_copy(batadv_ogm_packet->orig, + hard_iface->net_dev->dev_addr); + ether_addr_copy(batadv_ogm_packet->prev_sender, + hard_iface->net_dev->dev_addr); ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + static void + batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface) + { + struct batadv_ogm_packet *batadv_ogm_packet; +- unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff; ++ void *ogm_buff; + +- ASSERT_RTNL(); ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); + +- batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff; ++ ogm_buff = hard_iface->bat_iv.ogm_buff; ++ if (!ogm_buff) ++ goto unlock; ++ ++ batadv_ogm_packet = ogm_buff; + batadv_ogm_packet->ttl = BATADV_TTL; ++ ++unlock: ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); + } + + /* when do we schedule our own ogm to be sent */ +@@ -751,7 +772,11 @@ batadv_iv_ogm_slide_own_bcast_window(str + } + } + +-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++/** ++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer ++ * @hard_iface: interface whose ogm buffer should be transmitted ++ */ ++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) + { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff; +@@ -762,11 +787,7 @@ static void batadv_iv_ogm_schedule(struc + u16 tvlv_len = 0; + unsigned long send_time; + +- ASSERT_RTNL(); +- +- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || +- hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) +- return; ++ lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); + + /* the interface gets activated here to avoid race conditions between + * the moment of activating the interface in +@@ -834,6 +855,17 @@ out: + batadv_hardif_put(primary_if); + } + ++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ++{ ++ if (hard_iface->if_status == BATADV_IF_NOT_IN_USE || ++ hard_iface->if_status == BATADV_IF_TO_BE_REMOVED) ++ return; ++ ++ mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex); ++ batadv_iv_ogm_schedule_buff(hard_iface); ++ mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex); ++} ++ + /** + * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface + * @orig_node: originator which reproadcasted the OGMs directly +@@ -1654,12 +1686,16 @@ static void batadv_iv_ogm_process(const + batadv_orig_node_put(orig_node); + } + +-static void +-batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet) ++static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) + { ++ struct delayed_work *delayed_work; ++ struct batadv_forw_packet *forw_packet; + struct batadv_priv *bat_priv; + bool dropped = false; + ++ delayed_work = to_delayed_work(work); ++ forw_packet = container_of(delayed_work, struct batadv_forw_packet, ++ delayed_work); + bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); + + if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { +@@ -1688,20 +1724,6 @@ out: + batadv_forw_packet_free(forw_packet, dropped); + } + +-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) +-{ +- struct delayed_work *delayed_work; +- struct batadv_forw_packet *forw_packet; +- +- delayed_work = to_delayed_work(work); +- forw_packet = container_of(delayed_work, struct batadv_forw_packet, +- delayed_work); +- +- rtnl_lock(); +- batadv_iv_send_outstanding_forw_packet(forw_packet); +- rtnl_unlock(); +-} +- + static int batadv_iv_ogm_receive(struct sk_buff *skb, + struct batadv_hard_iface *if_incoming) + { +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -930,6 +931,7 @@ batadv_hardif_add_interface(struct net_d + INIT_LIST_HEAD(&hard_iface->list); + INIT_HLIST_HEAD(&hard_iface->neigh_list); + ++ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex); + spin_lock_init(&hard_iface->neigh_list_lock); + kref_init(&hard_iface->refcount); + +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -72,14 +72,17 @@ enum batadv_dhcp_recipient { + * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data + */ + struct batadv_hard_iface_bat_iv { +- /** @ogm_buff: buffer holding the OGM packet. rtnl protected */ ++ /** @ogm_buff: buffer holding the OGM packet */ + unsigned char *ogm_buff; + +- /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */ ++ /** @ogm_buff_len: length of the OGM packet buffer */ + int ogm_buff_len; + + /** @ogm_seqno: OGM sequence number - used to identify each OGM */ + atomic_t ogm_seqno; ++ ++ /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */ ++ struct mutex ogm_buff_mutex; + }; + + /** diff --git a/batman-adv/patches/0014-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch b/batman-adv/patches/0014-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch deleted file mode 100644 index fc9f5d9..0000000 --- a/batman-adv/patches/0014-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Sven Eckelmann -Date: Thu, 28 Nov 2019 12:43:49 +0100 -Subject: batman-adv: Fix DAT candidate selection on little endian systems - -The distributed arp table is using a DHT to store and retrieve MAC address -information for an IP address. This is done using unicast messages to -selected peers. The potential peers are looked up using the IP address and -the VID. - -While the IP address is always stored in big endian byte order, it is not -the case of the VID. It can (depending on the host system) either be big -endian or little endian. The host must therefore always convert it to big -endian to ensure that all devices calculate the same peers for the same -lookup data. - -Fixes: 3e26722bc9f2 ("batman-adv: make the Distributed ARP Table vlan aware") -Signed-off-by: Sven Eckelmann -Acked-by: Antonio Quartulli - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/728aea06f38e0e4d70f4f7d43698187f7f7055c5 - -diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c -index b0af3a11d4069cb7e44419d4494f20dd653dbca8..ec7bf5a4a9fc724b63da7bfd7ece79f32b104d99 100644 ---- a/net/batman-adv/distributed-arp-table.c -+++ b/net/batman-adv/distributed-arp-table.c -@@ -285,6 +285,7 @@ static u32 batadv_hash_dat(const void *data, u32 size) - u32 hash = 0; - const struct batadv_dat_entry *dat = data; - const unsigned char *key; -+ __be16 vid; - u32 i; - - key = (const unsigned char *)&dat->ip; -@@ -294,7 +295,8 @@ static u32 batadv_hash_dat(const void *data, u32 size) - hash ^= (hash >> 6); - } - -- key = (const unsigned char *)&dat->vid; -+ vid = htons(dat->vid); -+ key = (__force const unsigned char *)&vid; - for (i = 0; i < sizeof(dat->vid); i++) { - hash += key[i]; - hash += (hash << 10); diff --git a/batman-adv/patches/0015-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch b/batman-adv/patches/0015-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch deleted file mode 100644 index bf42a69..0000000 --- a/batman-adv/patches/0015-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Sven Eckelmann -Date: Sun, 16 Feb 2020 13:02:06 +0100 -Subject: batman-adv: Don't schedule OGM for disabled interface - -A transmission scheduling for an interface which is currently dropped by -batadv_iv_ogm_iface_disable could still be in progress. The B.A.T.M.A.N. V -is simply cancelling the workqueue item in an synchronous way but this is -not possible with B.A.T.M.A.N. IV because the OGM submissions are -intertwined. - -Instead it has to stop submitting the OGM when it detect that the buffer -pointer is set to NULL. - -Reported-by: syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com -Reported-by: syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com -Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") -Signed-off-by: Sven Eckelmann -Cc: Hillf Danton -Signed-off-by: Simon Wunderlich - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/a089c55ca004b396d340baae58abe9a79f32cc0f - -diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c -index 5b0b20e6da956b4333b118bce1c09c5acef6d66f..d88a4de0223727d25cf36839e46d7777449f025a 100644 ---- a/net/batman-adv/bat_iv_ogm.c -+++ b/net/batman-adv/bat_iv_ogm.c -@@ -789,6 +789,10 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface) - - lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); - -+ /* interface already disabled by batadv_iv_ogm_iface_disable */ -+ if (!*ogm_buff) -+ return; -+ - /* the interface gets activated here to avoid race conditions between - * the moment of activating the interface in - * hardif_activate_interface() where the originator mac is set and diff --git a/batman-adv/patches/0015-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch b/batman-adv/patches/0015-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch new file mode 100644 index 0000000..23a7ae4 --- /dev/null +++ b/batman-adv/patches/0015-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch @@ -0,0 +1,41 @@ +From: Sven Eckelmann +Date: Thu, 28 Nov 2019 12:43:49 +0100 +Subject: batman-adv: Fix DAT candidate selection on little endian systems + +The distributed arp table is using a DHT to store and retrieve MAC address +information for an IP address. This is done using unicast messages to +selected peers. The potential peers are looked up using the IP address and +the VID. + +While the IP address is always stored in big endian byte order, it is not +the case of the VID. It can (depending on the host system) either be big +endian or little endian. The host must therefore always convert it to big +endian to ensure that all devices calculate the same peers for the same +lookup data. + +Fixes: 3e26722bc9f2 ("batman-adv: make the Distributed ARP Table vlan aware") +Signed-off-by: Sven Eckelmann +Acked-by: Antonio Quartulli + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/728aea06f38e0e4d70f4f7d43698187f7f7055c5 + +--- a/net/batman-adv/distributed-arp-table.c ++++ b/net/batman-adv/distributed-arp-table.c +@@ -285,6 +285,7 @@ static u32 batadv_hash_dat(const void *d + u32 hash = 0; + const struct batadv_dat_entry *dat = data; + const unsigned char *key; ++ __be16 vid; + u32 i; + + key = (const unsigned char *)&dat->ip; +@@ -294,7 +295,8 @@ static u32 batadv_hash_dat(const void *d + hash ^= (hash >> 6); + } + +- key = (const unsigned char *)&dat->vid; ++ vid = htons(dat->vid); ++ key = (__force const unsigned char *)&vid; + for (i = 0; i < sizeof(dat->vid); i++) { + hash += key[i]; + hash += (hash << 10); diff --git a/batman-adv/patches/0016-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch b/batman-adv/patches/0016-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch new file mode 100644 index 0000000..99a2e02 --- /dev/null +++ b/batman-adv/patches/0016-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch @@ -0,0 +1,35 @@ +From: Sven Eckelmann +Date: Sun, 16 Feb 2020 13:02:06 +0100 +Subject: batman-adv: Don't schedule OGM for disabled interface + +A transmission scheduling for an interface which is currently dropped by +batadv_iv_ogm_iface_disable could still be in progress. The B.A.T.M.A.N. V +is simply cancelling the workqueue item in an synchronous way but this is +not possible with B.A.T.M.A.N. IV because the OGM submissions are +intertwined. + +Instead it has to stop submitting the OGM when it detect that the buffer +pointer is set to NULL. + +Reported-by: syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com +Reported-by: syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com +Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol") +Signed-off-by: Sven Eckelmann +Cc: Hillf Danton +Signed-off-by: Simon Wunderlich + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/a089c55ca004b396d340baae58abe9a79f32cc0f + +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -789,6 +789,10 @@ static void batadv_iv_ogm_schedule_buff( + + lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex); + ++ /* interface already disabled by batadv_iv_ogm_iface_disable */ ++ if (!*ogm_buff) ++ return; ++ + /* the interface gets activated here to avoid race conditions between + * the moment of activating the interface in + * hardif_activate_interface() where the originator mac is set and diff --git a/batman-adv/patches/0016-batman-adv-fix-batadv_nc_random_weight_tq.patch b/batman-adv/patches/0016-batman-adv-fix-batadv_nc_random_weight_tq.patch deleted file mode 100644 index 6a92197..0000000 --- a/batman-adv/patches/0016-batman-adv-fix-batadv_nc_random_weight_tq.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: George Spelvin -Date: Sun, 8 Mar 2020 09:44:59 -0400 -Subject: batman-adv: fix batadv_nc_random_weight_tq - -and change to pseudorandom numbers, as this is a traffic dithering -operation that doesn't need crypto-grade. - -The previous code operated in 4 steps: - -1. Generate a random byte 0 <= rand_tq <= 255 -2. Multiply it by BATADV_TQ_MAX_VALUE - tq -3. Divide by 255 (= BATADV_TQ_MAX_VALUE) -4. Return BATADV_TQ_MAX_VALUE - rand_tq - -This would apperar to scale (BATADV_TQ_MAX_VALUE - tq) by a random -value between 0/255 and 255/255. - -But! The intermediate value between steps 3 and 4 is stored in a u8 -variable. So it's truncated, and most of the time, is less than 255, after -which the division produces 0. Specifically, if tq is odd, the product is -always even, and can never be 255. If tq is even, there's exactly one -random byte value that will produce a product byte of 255. - -Thus, the return value is 255 (511/512 of the time) or 254 (1/512 -of the time). - -If we assume that the truncation is a bug, and the code is meant to scale -the input, a simpler way of looking at it is that it's returning a random -value between tq and BATADV_TQ_MAX_VALUE, inclusive. - -Well, we have an optimized function for doing just that. - -Fixes: c3289f3650d3 ("batman-adv: network coding - code and transmit packets if possible") -Signed-off-by: George Spelvin -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/db48c60b0edb995450ee846157364bd09bb23762 - -diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c -index c5e7906045f3c62c052400c44a18bca0a38499ba..b7f3d9ef83cfcc136888cd2487dcdd88cb16d6d9 100644 ---- a/net/batman-adv/network-coding.c -+++ b/net/batman-adv/network-coding.c -@@ -1009,15 +1009,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv, - */ - static u8 batadv_nc_random_weight_tq(u8 tq) - { -- u8 rand_val, rand_tq; -- -- get_random_bytes(&rand_val, sizeof(rand_val)); -- - /* randomize the estimated packet loss (max TQ - estimated TQ) */ -- rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq); -- -- /* normalize the randomized packet loss */ -- rand_tq /= BATADV_TQ_MAX_VALUE; -+ u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq); - - /* convert to (randomized) estimated tq again */ - return BATADV_TQ_MAX_VALUE - rand_tq; diff --git a/batman-adv/patches/0017-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch b/batman-adv/patches/0017-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch deleted file mode 100644 index 9ae0050..0000000 --- a/batman-adv/patches/0017-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Xiyu Yang -Date: Wed, 15 Apr 2020 16:31:50 +0800 -Subject: batman-adv: Fix refcnt leak in batadv_show_throughput_override - -batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), -which gets a batadv_hard_iface object from net_dev with increased refcnt -and its reference is assigned to a local pointer 'hard_iface'. - -When batadv_show_throughput_override() returns, "hard_iface" becomes -invalid, so the refcount should be decreased to keep refcount balanced. - -The issue happens in the normal path of -batadv_show_throughput_override(), which forgets to decrease the refcnt -increased by batadv_hardif_get_by_netdev() before the function returns, -causing a refcnt leak. - -Fix this issue by calling batadv_hardif_put() before the -batadv_show_throughput_override() returns in the normal path. - -Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces") -Signed-off-by: Xiyu Yang -Signed-off-by: Xin Tan -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f301bfed59b146a63471d0f147b767d7cafede6f - -diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c -index 80fc3253c3368e3cc356176c5ba961542de0a8c9..c20f2bab9db56021f7280ebdfc2afcfd772991bd 100644 ---- a/net/batman-adv/sysfs.c -+++ b/net/batman-adv/sysfs.c -@@ -1189,6 +1189,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj, - - tp_override = atomic_read(&hard_iface->bat_v.throughput_override); - -+ batadv_hardif_put(hard_iface); - return sprintf(buff, "%u.%u MBit\n", tp_override / 10, - tp_override % 10); - } diff --git a/batman-adv/patches/0017-batman-adv-fix-batadv_nc_random_weight_tq.patch b/batman-adv/patches/0017-batman-adv-fix-batadv_nc_random_weight_tq.patch new file mode 100644 index 0000000..1694f57 --- /dev/null +++ b/batman-adv/patches/0017-batman-adv-fix-batadv_nc_random_weight_tq.patch @@ -0,0 +1,57 @@ +From: George Spelvin +Date: Sun, 8 Mar 2020 09:44:59 -0400 +Subject: batman-adv: fix batadv_nc_random_weight_tq + +and change to pseudorandom numbers, as this is a traffic dithering +operation that doesn't need crypto-grade. + +The previous code operated in 4 steps: + +1. Generate a random byte 0 <= rand_tq <= 255 +2. Multiply it by BATADV_TQ_MAX_VALUE - tq +3. Divide by 255 (= BATADV_TQ_MAX_VALUE) +4. Return BATADV_TQ_MAX_VALUE - rand_tq + +This would apperar to scale (BATADV_TQ_MAX_VALUE - tq) by a random +value between 0/255 and 255/255. + +But! The intermediate value between steps 3 and 4 is stored in a u8 +variable. So it's truncated, and most of the time, is less than 255, after +which the division produces 0. Specifically, if tq is odd, the product is +always even, and can never be 255. If tq is even, there's exactly one +random byte value that will produce a product byte of 255. + +Thus, the return value is 255 (511/512 of the time) or 254 (1/512 +of the time). + +If we assume that the truncation is a bug, and the code is meant to scale +the input, a simpler way of looking at it is that it's returning a random +value between tq and BATADV_TQ_MAX_VALUE, inclusive. + +Well, we have an optimized function for doing just that. + +Fixes: c3289f3650d3 ("batman-adv: network coding - code and transmit packets if possible") +Signed-off-by: George Spelvin +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/db48c60b0edb995450ee846157364bd09bb23762 + +--- a/net/batman-adv/network-coding.c ++++ b/net/batman-adv/network-coding.c +@@ -1009,15 +1009,8 @@ static struct batadv_nc_path *batadv_nc_ + */ + static u8 batadv_nc_random_weight_tq(u8 tq) + { +- u8 rand_val, rand_tq; +- +- get_random_bytes(&rand_val, sizeof(rand_val)); +- + /* randomize the estimated packet loss (max TQ - estimated TQ) */ +- rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq); +- +- /* normalize the randomized packet loss */ +- rand_tq /= BATADV_TQ_MAX_VALUE; ++ u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq); + + /* convert to (randomized) estimated tq again */ + return BATADV_TQ_MAX_VALUE - rand_tq; diff --git a/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch b/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch new file mode 100644 index 0000000..725e4cf --- /dev/null +++ b/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch @@ -0,0 +1,36 @@ +From: Xiyu Yang +Date: Wed, 15 Apr 2020 16:31:50 +0800 +Subject: batman-adv: Fix refcnt leak in batadv_show_throughput_override + +batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), +which gets a batadv_hard_iface object from net_dev with increased refcnt +and its reference is assigned to a local pointer 'hard_iface'. + +When batadv_show_throughput_override() returns, "hard_iface" becomes +invalid, so the refcount should be decreased to keep refcount balanced. + +The issue happens in the normal path of +batadv_show_throughput_override(), which forgets to decrease the refcnt +increased by batadv_hardif_get_by_netdev() before the function returns, +causing a refcnt leak. + +Fix this issue by calling batadv_hardif_put() before the +batadv_show_throughput_override() returns in the normal path. + +Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces") +Signed-off-by: Xiyu Yang +Signed-off-by: Xin Tan +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f301bfed59b146a63471d0f147b767d7cafede6f + +--- a/net/batman-adv/sysfs.c ++++ b/net/batman-adv/sysfs.c +@@ -1189,6 +1189,7 @@ static ssize_t batadv_show_throughput_ov + + tp_override = atomic_read(&hard_iface->bat_v.throughput_override); + ++ batadv_hardif_put(hard_iface); + return sprintf(buff, "%u.%u MBit\n", tp_override / 10, + tp_override % 10); + } diff --git a/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch b/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch deleted file mode 100644 index 45f07db..0000000 --- a/batman-adv/patches/0018-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Xiyu Yang -Date: Wed, 15 Apr 2020 16:35:21 +0800 -Subject: batman-adv: Fix refcnt leak in batadv_store_throughput_override - -batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), -which gets a batadv_hard_iface object from net_dev with increased refcnt -and its reference is assigned to a local pointer 'hard_iface'. - -When batadv_store_throughput_override() returns, "hard_iface" becomes -invalid, so the refcount should be decreased to keep refcount balanced. - -The issue happens in one error path of -batadv_store_throughput_override(). When batadv_parse_throughput() -returns NULL, the refcnt increased by batadv_hardif_get_by_netdev() is -not decreased, causing a refcnt leak. - -Fix this issue by jumping to "out" label when batadv_parse_throughput() -returns NULL. - -Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces") -Signed-off-by: Xiyu Yang -Signed-off-by: Xin Tan -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/b69cd8bdbfd6fa7e61878c2fa9e6637406f40dd9 - -diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c -index c20f2bab9db56021f7280ebdfc2afcfd772991bd..34e9948fbd45ef6f2690052a208d6a4e4a4f215b 100644 ---- a/net/batman-adv/sysfs.c -+++ b/net/batman-adv/sysfs.c -@@ -1149,7 +1149,7 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj, - ret = batadv_parse_throughput(net_dev, buff, "throughput_override", - &tp_override); - if (!ret) -- return count; -+ goto out; - - old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override); - if (old_tp_override == tp_override) diff --git a/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch b/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch new file mode 100644 index 0000000..69ed250 --- /dev/null +++ b/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch @@ -0,0 +1,37 @@ +From: Xiyu Yang +Date: Wed, 15 Apr 2020 16:35:21 +0800 +Subject: batman-adv: Fix refcnt leak in batadv_store_throughput_override + +batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(), +which gets a batadv_hard_iface object from net_dev with increased refcnt +and its reference is assigned to a local pointer 'hard_iface'. + +When batadv_store_throughput_override() returns, "hard_iface" becomes +invalid, so the refcount should be decreased to keep refcount balanced. + +The issue happens in one error path of +batadv_store_throughput_override(). When batadv_parse_throughput() +returns NULL, the refcnt increased by batadv_hardif_get_by_netdev() is +not decreased, causing a refcnt leak. + +Fix this issue by jumping to "out" label when batadv_parse_throughput() +returns NULL. + +Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces") +Signed-off-by: Xiyu Yang +Signed-off-by: Xin Tan +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/b69cd8bdbfd6fa7e61878c2fa9e6637406f40dd9 + +--- a/net/batman-adv/sysfs.c ++++ b/net/batman-adv/sysfs.c +@@ -1149,7 +1149,7 @@ static ssize_t batadv_store_throughput_o + ret = batadv_parse_throughput(net_dev, buff, "throughput_override", + &tp_override); + if (!ret) +- return count; ++ goto out; + + old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override); + if (old_tp_override == tp_override) diff --git a/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch b/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch deleted file mode 100644 index 9f9db7d..0000000 --- a/batman-adv/patches/0019-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Xiyu Yang -Date: Mon, 20 Apr 2020 13:37:20 +0800 -Subject: batman-adv: Fix refcnt leak in batadv_v_ogm_process - -batadv_v_ogm_process() invokes batadv_hardif_neigh_get(), which returns -a reference of the neighbor object to "hardif_neigh" with increased -refcount. - -When batadv_v_ogm_process() returns, "hardif_neigh" becomes invalid, so -the refcount should be decreased to keep refcount balanced. - -The reference counting issue happens in one exception handling paths of -batadv_v_ogm_process(). When batadv_v_ogm_orig_get() fails to get the -orig node and returns NULL, the refcnt increased by -batadv_hardif_neigh_get() is not decreased, causing a refcnt leak. - -Fix this issue by jumping to "out" label when batadv_v_ogm_orig_get() -fails to get the orig node. - -Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic") -Signed-off-by: Xiyu Yang -Signed-off-by: Xin Tan -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/4515f5e6a4ccbe1c563b05f2d487eb9eef3c9740 - -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index 74452e9385b1a6e81be64af259dfc371cd3e9655..9c42152829c976a2fb6c4395ab4d17c34fe47682 100644 ---- a/net/batman-adv/bat_v_ogm.c -+++ b/net/batman-adv/bat_v_ogm.c -@@ -723,7 +723,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, - - orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig); - if (!orig_node) -- return; -+ goto out; - - neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming, - ethhdr->h_source); diff --git a/batman-adv/patches/0020-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch b/batman-adv/patches/0020-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch new file mode 100644 index 0000000..5c59f2f --- /dev/null +++ b/batman-adv/patches/0020-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch @@ -0,0 +1,37 @@ +From: Xiyu Yang +Date: Mon, 20 Apr 2020 13:37:20 +0800 +Subject: batman-adv: Fix refcnt leak in batadv_v_ogm_process + +batadv_v_ogm_process() invokes batadv_hardif_neigh_get(), which returns +a reference of the neighbor object to "hardif_neigh" with increased +refcount. + +When batadv_v_ogm_process() returns, "hardif_neigh" becomes invalid, so +the refcount should be decreased to keep refcount balanced. + +The reference counting issue happens in one exception handling paths of +batadv_v_ogm_process(). When batadv_v_ogm_orig_get() fails to get the +orig node and returns NULL, the refcnt increased by +batadv_hardif_neigh_get() is not decreased, causing a refcnt leak. + +Fix this issue by jumping to "out" label when batadv_v_ogm_orig_get() +fails to get the orig node. + +Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic") +Signed-off-by: Xiyu Yang +Signed-off-by: Xin Tan +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/4515f5e6a4ccbe1c563b05f2d487eb9eef3c9740 + +--- a/net/batman-adv/bat_v_ogm.c ++++ b/net/batman-adv/bat_v_ogm.c +@@ -723,7 +723,7 @@ static void batadv_v_ogm_process(const s + + orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig); + if (!orig_node) +- return; ++ goto out; + + neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming, + ethhdr->h_source); diff --git a/batman-adv/patches/0020-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch b/batman-adv/patches/0020-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch deleted file mode 100644 index 0de7d25..0000000 --- a/batman-adv/patches/0020-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch +++ /dev/null @@ -1,76 +0,0 @@ -From: Sven Eckelmann -Date: Mon, 25 Nov 2019 10:46:50 +0100 -Subject: batman-adv: Revert "disable ethtool link speed detection when auto negotiation off" - -The commit d60b8fc69ef2 ("batman-adv: disable ethtool link speed detection -when auto negotiation off") disabled the usage of ethtool's link_ksetting -when auto negotation was enabled due to invalid values when used with -tun/tap virtual net_devices. According to the patch, automatic measurements -should be used for these kind of interfaces. - -But there are major flaws with this argumentation: - -* automatic measurements are not implemented -* auto negotiation has nothing to do with the validity of the retrieved - values - -The first point has to be fixed by a longer patch series. The "validity" -part of the second point must be addressed in the same patch series by -dropping the usage of ethtool's link_ksetting (thus always doing automatic -measurements over ethernet). - -Drop the patch again to have more default values for various net_device -types/configurations. The user can still overwrite them using the -batadv_hardif's BATADV_ATTR_THROUGHPUT_OVERRIDE. - -Reported-by: Matthias Schiffer -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e860b3d5e4147bafcda32bf9b3e769926f232c5 - -diff --git a/compat-include/linux/ethtool.h b/compat-include/linux/ethtool.h -index e1f39c3377febbd650a75206aafa9ae3e807762a..8dcbe02c3decf941e892af70a0a67653b010e65e 100644 ---- a/compat-include/linux/ethtool.h -+++ b/compat-include/linux/ethtool.h -@@ -21,7 +21,6 @@ struct batadv_ethtool_link_ksettings { - struct { - __u32 speed; - __u8 duplex; -- __u8 autoneg; - } base; - }; - -@@ -42,7 +41,6 @@ batadv_ethtool_get_link_ksettings(struct net_device *dev, - return ret; - - link_ksettings->base.duplex = cmd.duplex; -- link_ksettings->base.autoneg = cmd.autoneg; - link_ksettings->base.speed = ethtool_cmd_speed(&cmd); - - return 0; -diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c -index 2614a9caee008539cc489b71dabdc36ac0ae3752..a39af0eefad313101812118181ec0376b21b79bb 100644 ---- a/net/batman-adv/bat_v_elp.c -+++ b/net/batman-adv/bat_v_elp.c -@@ -120,20 +120,7 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) - rtnl_lock(); - ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); - rtnl_unlock(); -- -- /* Virtual interface drivers such as tun / tap interfaces, VLAN, etc -- * tend to initialize the interface throughput with some value for the -- * sake of having a throughput number to export via ethtool. This -- * exported throughput leaves batman-adv to conclude the interface -- * throughput is genuine (reflecting reality), thus no measurements -- * are necessary. -- * -- * Based on the observation that those interface types also tend to set -- * the link auto-negotiation to 'off', batman-adv shall check this -- * setting to differentiate between genuine link throughput information -- * and placeholders installed by virtual interfaces. -- */ -- if (ret == 0 && link_settings.base.autoneg == AUTONEG_ENABLE) { -+ if (ret == 0) { - /* link characteristics might change over time */ - if (link_settings.base.duplex == DUPLEX_FULL) - hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX; diff --git a/batman-adv/patches/0021-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch b/batman-adv/patches/0021-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch deleted file mode 100644 index 1b36259..0000000 --- a/batman-adv/patches/0021-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Sven Eckelmann -Date: Wed, 22 Jul 2020 20:49:23 +0200 -Subject: batman-adv: Avoid uninitialized chaddr when handling DHCP - -The gateway client code can try to optimize the delivery of DHCP packets to -avoid broadcasting them through the whole mesh. But also transmissions to -the client can be optimized by looking up the destination via the chaddr of -the DHCP packet. - -But the chaddr is currently only done when chaddr is fully inside the -non-paged area of the skbuff. Otherwise it will not be initialized and the -unoptimized path should have been taken. - -But the implementation didn't handle this correctly. It didn't retrieve the -correct chaddr but still tried to perform the TT lookup with this -uninitialized memory. - -Reported-by: syzbot+ab16e463b903f5a37036@syzkaller.appspotmail.com -Fixes: 2d5b555644b2 ("batman-adv: send every DHCP packet as bat-unicast") -Signed-off-by: Sven Eckelmann -Acked-by: Antonio Quartulli -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fcdf008ffd749246632d1f9423163af5dc3f8c7f - -diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c -index 47df4c678988613f7410acb96889558eabdf396d..89c9097007c3a575836018df9e0fe97731a19619 100644 ---- a/net/batman-adv/gateway_client.c -+++ b/net/batman-adv/gateway_client.c -@@ -703,8 +703,10 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len, - - chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET; - /* store the client address if the message is going to a client */ -- if (ret == BATADV_DHCP_TO_CLIENT && -- pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) { -+ if (ret == BATADV_DHCP_TO_CLIENT) { -+ if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) -+ return BATADV_DHCP_NO; -+ - /* check if the DHCP packet carries an Ethernet DHCP */ - p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET; - if (*p != BATADV_DHCP_HTYPE_ETHERNET) diff --git a/batman-adv/patches/0021-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch b/batman-adv/patches/0021-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch new file mode 100644 index 0000000..adc6ba9 --- /dev/null +++ b/batman-adv/patches/0021-batman-adv-Revert-disable-ethtool-link-speed-detecti.patch @@ -0,0 +1,72 @@ +From: Sven Eckelmann +Date: Mon, 25 Nov 2019 10:46:50 +0100 +Subject: batman-adv: Revert "disable ethtool link speed detection when auto negotiation off" + +The commit d60b8fc69ef2 ("batman-adv: disable ethtool link speed detection +when auto negotiation off") disabled the usage of ethtool's link_ksetting +when auto negotation was enabled due to invalid values when used with +tun/tap virtual net_devices. According to the patch, automatic measurements +should be used for these kind of interfaces. + +But there are major flaws with this argumentation: + +* automatic measurements are not implemented +* auto negotiation has nothing to do with the validity of the retrieved + values + +The first point has to be fixed by a longer patch series. The "validity" +part of the second point must be addressed in the same patch series by +dropping the usage of ethtool's link_ksetting (thus always doing automatic +measurements over ethernet). + +Drop the patch again to have more default values for various net_device +types/configurations. The user can still overwrite them using the +batadv_hardif's BATADV_ATTR_THROUGHPUT_OVERRIDE. + +Reported-by: Matthias Schiffer +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e860b3d5e4147bafcda32bf9b3e769926f232c5 + +--- a/compat-include/linux/ethtool.h ++++ b/compat-include/linux/ethtool.h +@@ -21,7 +21,6 @@ struct batadv_ethtool_link_ksettings { + struct { + __u32 speed; + __u8 duplex; +- __u8 autoneg; + } base; + }; + +@@ -42,7 +41,6 @@ batadv_ethtool_get_link_ksettings(struct + return ret; + + link_ksettings->base.duplex = cmd.duplex; +- link_ksettings->base.autoneg = cmd.autoneg; + link_ksettings->base.speed = ethtool_cmd_speed(&cmd); + + return 0; +--- a/net/batman-adv/bat_v_elp.c ++++ b/net/batman-adv/bat_v_elp.c +@@ -120,20 +120,7 @@ static u32 batadv_v_elp_get_throughput(s + rtnl_lock(); + ret = __ethtool_get_link_ksettings(hard_iface->net_dev, &link_settings); + rtnl_unlock(); +- +- /* Virtual interface drivers such as tun / tap interfaces, VLAN, etc +- * tend to initialize the interface throughput with some value for the +- * sake of having a throughput number to export via ethtool. This +- * exported throughput leaves batman-adv to conclude the interface +- * throughput is genuine (reflecting reality), thus no measurements +- * are necessary. +- * +- * Based on the observation that those interface types also tend to set +- * the link auto-negotiation to 'off', batman-adv shall check this +- * setting to differentiate between genuine link throughput information +- * and placeholders installed by virtual interfaces. +- */ +- if (ret == 0 && link_settings.base.autoneg == AUTONEG_ENABLE) { ++ if (ret == 0) { + /* link characteristics might change over time */ + if (link_settings.base.duplex == DUPLEX_FULL) + hard_iface->bat_v.flags |= BATADV_FULL_DUPLEX; diff --git a/batman-adv/patches/0022-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch b/batman-adv/patches/0022-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch new file mode 100644 index 0000000..9d14c6d --- /dev/null +++ b/batman-adv/patches/0022-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch @@ -0,0 +1,40 @@ +From: Sven Eckelmann +Date: Wed, 22 Jul 2020 20:49:23 +0200 +Subject: batman-adv: Avoid uninitialized chaddr when handling DHCP + +The gateway client code can try to optimize the delivery of DHCP packets to +avoid broadcasting them through the whole mesh. But also transmissions to +the client can be optimized by looking up the destination via the chaddr of +the DHCP packet. + +But the chaddr is currently only done when chaddr is fully inside the +non-paged area of the skbuff. Otherwise it will not be initialized and the +unoptimized path should have been taken. + +But the implementation didn't handle this correctly. It didn't retrieve the +correct chaddr but still tried to perform the TT lookup with this +uninitialized memory. + +Reported-by: syzbot+ab16e463b903f5a37036@syzkaller.appspotmail.com +Fixes: 2d5b555644b2 ("batman-adv: send every DHCP packet as bat-unicast") +Signed-off-by: Sven Eckelmann +Acked-by: Antonio Quartulli +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fcdf008ffd749246632d1f9423163af5dc3f8c7f + +--- a/net/batman-adv/gateway_client.c ++++ b/net/batman-adv/gateway_client.c +@@ -703,8 +703,10 @@ batadv_gw_dhcp_recipient_get(struct sk_b + + chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET; + /* store the client address if the message is going to a client */ +- if (ret == BATADV_DHCP_TO_CLIENT && +- pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) { ++ if (ret == BATADV_DHCP_TO_CLIENT) { ++ if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) ++ return BATADV_DHCP_NO; ++ + /* check if the DHCP packet carries an Ethernet DHCP */ + p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET; + if (*p != BATADV_DHCP_HTYPE_ETHERNET) diff --git a/batman-adv/patches/0022-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch b/batman-adv/patches/0022-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch deleted file mode 100644 index e1db268..0000000 --- a/batman-adv/patches/0022-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: Linus Lüssing -Date: Fri, 31 Jul 2020 00:22:55 +0200 -Subject: batman-adv: Fix own OGM check in aggregated OGMs - -The own OGM check is currently misplaced and can lead to the following -issues: - -For one thing we might receive an aggregated OGM from a neighbor node -which has our own OGM in the first place. We would then not only skip -our own OGM but erroneously also any other, following OGM in the -aggregate. - -For another, we might receive an OGM aggregate which has our own OGM in -a place other then the first one. Then we would wrongly not skip this -OGM, leading to populating the orginator and gateway table with ourself. - -The latter seems to not only be a cosmetic issue, but there were reports -that this causes issues with various subsystems of batman-adv, too. For -instance there were reports about issues with DAT and either disabling -DAT or aggregation seemed to solve it. - -Fixing these issues by applying the own OGM check not on the first OGM -in an aggregate but for each OGM in an aggregate instead. - -Fixes: 667996ebeab ("batman-adv: OGMv2 - implement originators logic") -Signed-off-by: Linus Lüssing -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d41cc7cb62c184b2fb8ab97fda45815918200001 - -diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c -index 9c42152829c976a2fb6c4395ab4d17c34fe47682..330204a73a0d3d9e4083656b82ff7b9d73a48fdc 100644 ---- a/net/batman-adv/bat_v_ogm.c -+++ b/net/batman-adv/bat_v_ogm.c -@@ -704,6 +704,12 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, - ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl, - ogm_packet->version, ntohs(ogm_packet->tvlv_len)); - -+ if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) { -+ batadv_dbg(BATADV_DBG_BATMAN, bat_priv, -+ "Drop packet: originator packet from ourself\n"); -+ return; -+ } -+ - /* If the throughput metric is 0, immediately drop the packet. No need - * to create orig_node / neigh_node for an unusable route. - */ -@@ -831,11 +837,6 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb, - if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) - goto free_skb; - -- ogm_packet = (struct batadv_ogm2_packet *)skb->data; -- -- if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) -- goto free_skb; -- - batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX); - batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES, - skb->len + ETH_HLEN); diff --git a/batman-adv/patches/0023-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch b/batman-adv/patches/0023-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch new file mode 100644 index 0000000..6bda396 --- /dev/null +++ b/batman-adv/patches/0023-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch @@ -0,0 +1,57 @@ +From: Linus Lüssing +Date: Fri, 31 Jul 2020 00:22:55 +0200 +Subject: batman-adv: Fix own OGM check in aggregated OGMs + +The own OGM check is currently misplaced and can lead to the following +issues: + +For one thing we might receive an aggregated OGM from a neighbor node +which has our own OGM in the first place. We would then not only skip +our own OGM but erroneously also any other, following OGM in the +aggregate. + +For another, we might receive an OGM aggregate which has our own OGM in +a place other then the first one. Then we would wrongly not skip this +OGM, leading to populating the orginator and gateway table with ourself. + +The latter seems to not only be a cosmetic issue, but there were reports +that this causes issues with various subsystems of batman-adv, too. For +instance there were reports about issues with DAT and either disabling +DAT or aggregation seemed to solve it. + +Fixing these issues by applying the own OGM check not on the first OGM +in an aggregate but for each OGM in an aggregate instead. + +Fixes: 667996ebeab ("batman-adv: OGMv2 - implement originators logic") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d41cc7cb62c184b2fb8ab97fda45815918200001 + +--- a/net/batman-adv/bat_v_ogm.c ++++ b/net/batman-adv/bat_v_ogm.c +@@ -704,6 +704,12 @@ static void batadv_v_ogm_process(const s + ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl, + ogm_packet->version, ntohs(ogm_packet->tvlv_len)); + ++ if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) { ++ batadv_dbg(BATADV_DBG_BATMAN, bat_priv, ++ "Drop packet: originator packet from ourself\n"); ++ return; ++ } ++ + /* If the throughput metric is 0, immediately drop the packet. No need + * to create orig_node / neigh_node for an unusable route. + */ +@@ -831,11 +837,6 @@ int batadv_v_ogm_packet_recv(struct sk_b + if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) + goto free_skb; + +- ogm_packet = (struct batadv_ogm2_packet *)skb->data; +- +- if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) +- goto free_skb; +- + batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX); + batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES, + skb->len + ETH_HLEN); diff --git a/batman-adv/patches/0023-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch b/batman-adv/patches/0023-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch deleted file mode 100644 index 53baee8..0000000 --- a/batman-adv/patches/0023-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Jussi Kivilinna -Date: Tue, 18 Aug 2020 17:46:10 +0300 -Subject: batman-adv: bla: use netif_rx_ni when not in interrupt context - -batadv_bla_send_claim() gets called from worker thread context through -batadv_bla_periodic_work(), thus netif_rx_ni needs to be used in that -case. This fixes "NOHZ: local_softirq_pending 08" log messages seen -when batman-adv is enabled. - -Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code") -Signed-off-by: Jussi Kivilinna -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3747f81a1380b65740fc52fc71c7a3af4c6e49de - -diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c -index 663a53b6d36e65508b4296d86cecdd808c653836..5f6309ade1ea19f6a0bd27e8cbc5fcfba8f7dda5 100644 ---- a/net/batman-adv/bridge_loop_avoidance.c -+++ b/net/batman-adv/bridge_loop_avoidance.c -@@ -437,7 +437,10 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac, - batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, - skb->len + ETH_HLEN); - -- netif_rx(skb); -+ if (in_interrupt()) -+ netif_rx(skb); -+ else -+ netif_rx_ni(skb); - out: - if (primary_if) - batadv_hardif_put(primary_if); diff --git a/batman-adv/patches/0024-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch b/batman-adv/patches/0024-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch deleted file mode 100644 index 35d96e3..0000000 --- a/batman-adv/patches/0024-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Linus Lüssing -Date: Thu, 27 Aug 2020 17:34:48 +0200 -Subject: batman-adv: bla: fix type misuse for backbone_gw hash indexing - -It seems that due to a copy & paste error the void pointer -in batadv_choose_backbone_gw() is cast to the wrong type. - -Fixing this by using "struct batadv_bla_backbone_gw" instead of "struct -batadv_bla_claim" which better matches the caller's side. - -For now it seems that we were lucky because the two structs both have -their orig/vid and addr/vid in the beginning. However I stumbled over -this issue when I was trying to add some debug variables in front of -"orig" in batadv_backbone_gw, which caused hash lookups to fail. - -Fixes: 7e15c9305ce0 ("batman-adv: don't rely on positions in struct for hashing") -Signed-off-by: Linus Lüssing -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/398a706cd46c1fc085aef56ae8ed11f76e182bd1 - -diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c -index 5f6309ade1ea19f6a0bd27e8cbc5fcfba8f7dda5..62d2e766dd3929e54070c13225f0f71c7f59a212 100644 ---- a/net/batman-adv/bridge_loop_avoidance.c -+++ b/net/batman-adv/bridge_loop_avoidance.c -@@ -83,11 +83,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size) - */ - static inline u32 batadv_choose_backbone_gw(const void *data, u32 size) - { -- const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data; -+ const struct batadv_bla_backbone_gw *gw; - u32 hash = 0; - -- hash = jhash(&claim->addr, sizeof(claim->addr), hash); -- hash = jhash(&claim->vid, sizeof(claim->vid), hash); -+ gw = (struct batadv_bla_backbone_gw *)data; -+ hash = jhash(&gw->orig, sizeof(gw->orig), hash); -+ hash = jhash(&gw->vid, sizeof(gw->vid), hash); - - return hash % size; - } diff --git a/batman-adv/patches/0024-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch b/batman-adv/patches/0024-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch new file mode 100644 index 0000000..4d5634f --- /dev/null +++ b/batman-adv/patches/0024-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch @@ -0,0 +1,29 @@ +From: Jussi Kivilinna +Date: Tue, 18 Aug 2020 17:46:10 +0300 +Subject: batman-adv: bla: use netif_rx_ni when not in interrupt context + +batadv_bla_send_claim() gets called from worker thread context through +batadv_bla_periodic_work(), thus netif_rx_ni needs to be used in that +case. This fixes "NOHZ: local_softirq_pending 08" log messages seen +when batman-adv is enabled. + +Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code") +Signed-off-by: Jussi Kivilinna +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3747f81a1380b65740fc52fc71c7a3af4c6e49de + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -437,7 +437,10 @@ static void batadv_bla_send_claim(struct + batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, + skb->len + ETH_HLEN); + +- netif_rx(skb); ++ if (in_interrupt()) ++ netif_rx(skb); ++ else ++ netif_rx_ni(skb); + out: + if (primary_if) + batadv_hardif_put(primary_if); diff --git a/batman-adv/patches/0025-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch b/batman-adv/patches/0025-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch new file mode 100644 index 0000000..4799d6a --- /dev/null +++ b/batman-adv/patches/0025-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch @@ -0,0 +1,39 @@ +From: Linus Lüssing +Date: Thu, 27 Aug 2020 17:34:48 +0200 +Subject: batman-adv: bla: fix type misuse for backbone_gw hash indexing + +It seems that due to a copy & paste error the void pointer +in batadv_choose_backbone_gw() is cast to the wrong type. + +Fixing this by using "struct batadv_bla_backbone_gw" instead of "struct +batadv_bla_claim" which better matches the caller's side. + +For now it seems that we were lucky because the two structs both have +their orig/vid and addr/vid in the beginning. However I stumbled over +this issue when I was trying to add some debug variables in front of +"orig" in batadv_backbone_gw, which caused hash lookups to fail. + +Fixes: 7e15c9305ce0 ("batman-adv: don't rely on positions in struct for hashing") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/398a706cd46c1fc085aef56ae8ed11f76e182bd1 + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -83,11 +83,12 @@ static inline u32 batadv_choose_claim(co + */ + static inline u32 batadv_choose_backbone_gw(const void *data, u32 size) + { +- const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data; ++ const struct batadv_bla_backbone_gw *gw; + u32 hash = 0; + +- hash = jhash(&claim->addr, sizeof(claim->addr), hash); +- hash = jhash(&claim->vid, sizeof(claim->vid), hash); ++ gw = (struct batadv_bla_backbone_gw *)data; ++ hash = jhash(&gw->orig, sizeof(gw->orig), hash); ++ hash = jhash(&gw->vid, sizeof(gw->vid), hash); + + return hash % size; + } diff --git a/batman-adv/patches/0025-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch b/batman-adv/patches/0025-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch deleted file mode 100644 index 34e9557..0000000 --- a/batman-adv/patches/0025-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Linus Lüssing -Date: Fri, 4 Sep 2020 20:28:00 +0200 -Subject: batman-adv: mcast/TT: fix wrongly dropped or rerouted packets - -The unicast packet rerouting code makes several assumptions. For -instance it assumes that there is always exactly one destination in the -TT. This breaks for multicast frames in a unicast packets in several ways: - -For one thing if there is actually no TT entry and the destination node -was selected due to the multicast tvlv flags it announced. Then an -intermediate node will wrongly drop the packet. - -For another thing if there is a TT entry but the TTVN of this entry is -newer than the originally addressed destination node: Then the -intermediate node will wrongly redirect the packet, leading to -duplicated multicast packets at a multicast listener and missing -packets at other multicast listeners or multicast routers. - -Fixing this by not applying the unicast packet rerouting to batman-adv -unicast packets with a multicast payload. We are not able to detect a -roaming multicast listener at the moment and will just continue to send -the multicast frame to both the new and old destination for a while in -case of such a roaming multicast listener. - -Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism") -Signed-off-by: Linus Lüssing -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22e740c5e6c9342e0f5028beb3d14b84a018d113 - -diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c -index f0f864820dead3e7811a6b0d522ec84954d9aec2..708e90cb18a6e95409f50e41708d903dd8301f9c 100644 ---- a/net/batman-adv/routing.c -+++ b/net/batman-adv/routing.c -@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, - vid = batadv_get_vid(skb, hdr_len); - ethhdr = (struct ethhdr *)(skb->data + hdr_len); - -+ /* do not reroute multicast frames in a unicast header */ -+ if (is_multicast_ether_addr(ethhdr->h_dest)) -+ return true; -+ - /* check if the destination client was served by this node and it is now - * roaming. In this case, it means that the node has got a ROAM_ADV - * message and that it knows the new destination in the mesh to re-route diff --git a/batman-adv/patches/0026-batman-adv-Add-missing-include-for-in_interrupt.patch b/batman-adv/patches/0026-batman-adv-Add-missing-include-for-in_interrupt.patch deleted file mode 100644 index 9c6850a..0000000 --- a/batman-adv/patches/0026-batman-adv-Add-missing-include-for-in_interrupt.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Sven Eckelmann -Date: Mon, 14 Sep 2020 13:58:16 +0200 -Subject: batman-adv: Add missing include for in_interrupt() - -The fix for receiving (internally generated) bla packets outside the -interrupt context introduced the usage of in_interrupt(). But this -functionality is only defined in linux/preempt.h which was not included -with the same patch. - -Fixes: 3747f81a1380 ("batman-adv: bla: use netif_rx_ni when not in interrupt context") -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6ea99cd9c82b2d1bc4a313fe9006bcf5d956380e - -diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c -index 62d2e766dd3929e54070c13225f0f71c7f59a212..fe406c17b2c0aa24f49a7d5dee4264fbca56d72f 100644 ---- a/net/batman-adv/bridge_loop_avoidance.c -+++ b/net/batman-adv/bridge_loop_avoidance.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/batman-adv/patches/0026-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch b/batman-adv/patches/0026-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch new file mode 100644 index 0000000..2a9b1ae --- /dev/null +++ b/batman-adv/patches/0026-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch @@ -0,0 +1,43 @@ +From: Linus Lüssing +Date: Fri, 4 Sep 2020 20:28:00 +0200 +Subject: batman-adv: mcast/TT: fix wrongly dropped or rerouted packets + +The unicast packet rerouting code makes several assumptions. For +instance it assumes that there is always exactly one destination in the +TT. This breaks for multicast frames in a unicast packets in several ways: + +For one thing if there is actually no TT entry and the destination node +was selected due to the multicast tvlv flags it announced. Then an +intermediate node will wrongly drop the packet. + +For another thing if there is a TT entry but the TTVN of this entry is +newer than the originally addressed destination node: Then the +intermediate node will wrongly redirect the packet, leading to +duplicated multicast packets at a multicast listener and missing +packets at other multicast listeners or multicast routers. + +Fixing this by not applying the unicast packet rerouting to batman-adv +unicast packets with a multicast payload. We are not able to detect a +roaming multicast listener at the moment and will just continue to send +the multicast frame to both the new and old destination for a while in +case of such a roaming multicast listener. + +Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22e740c5e6c9342e0f5028beb3d14b84a018d113 + +--- a/net/batman-adv/routing.c ++++ b/net/batman-adv/routing.c +@@ -826,6 +826,10 @@ static bool batadv_check_unicast_ttvn(st + vid = batadv_get_vid(skb, hdr_len); + ethhdr = (struct ethhdr *)(skb->data + hdr_len); + ++ /* do not reroute multicast frames in a unicast header */ ++ if (is_multicast_ether_addr(ethhdr->h_dest)) ++ return true; ++ + /* check if the destination client was served by this node and it is now + * roaming. In this case, it means that the node has got a ROAM_ADV + * message and that it knows the new destination in the mesh to re-route diff --git a/batman-adv/patches/0027-batman-adv-Add-missing-include-for-in_interrupt.patch b/batman-adv/patches/0027-batman-adv-Add-missing-include-for-in_interrupt.patch new file mode 100644 index 0000000..a9eead3 --- /dev/null +++ b/batman-adv/patches/0027-batman-adv-Add-missing-include-for-in_interrupt.patch @@ -0,0 +1,24 @@ +From: Sven Eckelmann +Date: Mon, 14 Sep 2020 13:58:16 +0200 +Subject: batman-adv: Add missing include for in_interrupt() + +The fix for receiving (internally generated) bla packets outside the +interrupt context introduced the usage of in_interrupt(). But this +functionality is only defined in linux/preempt.h which was not included +with the same patch. + +Fixes: 3747f81a1380 ("batman-adv: bla: use netif_rx_ni when not in interrupt context") +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6ea99cd9c82b2d1bc4a313fe9006bcf5d956380e + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/batman-adv/patches/0027-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch b/batman-adv/patches/0027-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch deleted file mode 100644 index 5d548f5..0000000 --- a/batman-adv/patches/0027-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch +++ /dev/null @@ -1,170 +0,0 @@ -From: Linus Lüssing -Date: Tue, 15 Sep 2020 09:54:08 +0200 -Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN - -Scenario: -* Multicast frame send from a BLA backbone (multiple nodes with - their bat0 bridged together, with BLA enabled) - -Issue: -* BLA backbone nodes receive the frame multiple times on bat0 - -For multicast frames received via batman-adv broadcast packets the -originator of the broadcast packet is checked before decapsulating and -forwarding the frame to bat0 (batadv_bla_is_backbone_gw()-> -batadv_recv_bcast_packet()). If it came from a node which shares the -same BLA backbone with us then it is not forwarded to bat0 to avoid a -loop. - -When sending a multicast frame in a non-4-address batman-adv unicast -packet we are currently missing this check - and cannot do so because -the batman-adv unicast packet has no originator address field. - -However, we can simply fix this on the sender side by only sending the -multicast frame via unicasts to interested nodes which do not share the -same BLA backbone with us. This also nicely avoids some unnecessary -transmissions on mesh side. - -Note that no infinite loop was observed, probably because of dropping -via batadv_interface_tx()->batadv_bla_tx(). However the duplicates still -utterly confuse switches/bridges, ICMPv6 duplicate address detection and -neighbor discovery and therefore leads to long delays before being able -to establish TCP connections, for instance. And it also leads to the Linux -bridge printing messages like: -"br-lan: received packet on eth1 with own address as source address ..." - -Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets") -Signed-off-by: Linus Lüssing -Acked-by: Simon Wunderlich -Signed-off-by: Sven Eckelmann - -Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/3c39a2455a5be02ecceeaf1a15976bddd611392e - -diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c -index 50fe9dfb088b60a911756c8c22cac1db6ef10ca4..6f3a39ca274304c5d2196c2366291cd43ff234d5 100644 ---- a/net/batman-adv/multicast.c -+++ b/net/batman-adv/multicast.c -@@ -50,6 +50,7 @@ - #include - #include - -+#include "bridge_loop_avoidance.h" - #include "hard-interface.h" - #include "hash.h" - #include "log.h" -@@ -1019,6 +1020,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, - return BATADV_FORW_ALL; - } - -+/** -+ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator -+ * @bat_priv: the bat priv with all the soft interface information -+ * @skb: the multicast packet to send -+ * @vid: the vlan identifier -+ * @orig_node: the originator to send the packet to -+ * -+ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. -+ */ -+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, -+ struct sk_buff *skb, -+ unsigned short vid, -+ struct batadv_orig_node *orig_node) -+{ -+ /* Avoid sending multicast-in-unicast packets to other BLA -+ * gateways - they already got the frame from the LAN side -+ * we share with them. -+ * TODO: Refactor to take BLA into account earlier, to avoid -+ * reducing the mcast_fanout count. -+ */ -+ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) { -+ dev_kfree_skb(skb); -+ return NET_XMIT_SUCCESS; -+ } -+ -+ return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0, -+ orig_node, vid); -+} -+ - /** - * batadv_mcast_forw_tt() - forwards a packet to multicast listeners - * @bat_priv: the bat priv with all the soft interface information -@@ -1056,8 +1086,8 @@ batadv_mcast_forw_tt(struct batadv_priv *bat_priv, struct sk_buff *skb, - break; - } - -- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, -- orig_entry->orig_node, vid); -+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, -+ orig_entry->orig_node); - } - rcu_read_unlock(); - -@@ -1098,8 +1128,7 @@ batadv_mcast_forw_want_all_ipv4(struct batadv_priv *bat_priv, - break; - } - -- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, -- orig_node, vid); -+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); - } - rcu_read_unlock(); - return ret; -@@ -1136,8 +1165,7 @@ batadv_mcast_forw_want_all_ipv6(struct batadv_priv *bat_priv, - break; - } - -- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, -- orig_node, vid); -+ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); - } - rcu_read_unlock(); - return ret; -diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h -index 653b9b76fabe68ee7dbe038ef86b7e631848c18a..a97e7f54b9fe58e980ba46b32c1a645e218d1f31 100644 ---- a/net/batman-adv/multicast.h -+++ b/net/batman-adv/multicast.h -@@ -46,6 +46,11 @@ enum batadv_forw_mode - batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, - struct batadv_orig_node **mcast_single_orig); - -+int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, -+ struct sk_buff *skb, -+ unsigned short vid, -+ struct batadv_orig_node *orig_node); -+ - int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, - unsigned short vid); - -@@ -71,6 +76,16 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, - return BATADV_FORW_ALL; - } - -+static inline int -+batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, -+ struct sk_buff *skb, -+ unsigned short vid, -+ struct batadv_orig_node *orig_node) -+{ -+ kfree_skb(skb); -+ return NET_XMIT_DROP; -+} -+ - static inline int - batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, - unsigned short vid) -diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c -index a7677e1d000fbc6ab60466cf5fc4f1750014268e..164cc254ef6f621ef7b8fb666821d8997188664f 100644 ---- a/net/batman-adv/soft-interface.c -+++ b/net/batman-adv/soft-interface.c -@@ -363,9 +363,8 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, - goto dropped; - ret = batadv_send_skb_via_gw(bat_priv, skb, vid); - } else if (mcast_single_orig) { -- ret = batadv_send_skb_unicast(bat_priv, skb, -- BATADV_UNICAST, 0, -- mcast_single_orig, vid); -+ ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid, -+ mcast_single_orig); - } else if (forw_mode == BATADV_FORW_SOME) { - ret = batadv_mcast_forw_send(bat_priv, skb, vid); - } else { diff --git a/batman-adv/patches/0028-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch b/batman-adv/patches/0028-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch index 8169b0f..bebcd02 100644 --- a/batman-adv/patches/0028-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch +++ b/batman-adv/patches/0028-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch @@ -1,156 +1,164 @@ From: Linus Lüssing -Date: Tue, 15 Sep 2020 09:54:09 +0200 -Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh +Date: Tue, 15 Sep 2020 09:54:08 +0200 +Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN Scenario: -* Multicast frame send from mesh to a BLA backbone (multiple nodes - with their bat0 bridged together, with BLA enabled) +* Multicast frame send from a BLA backbone (multiple nodes with + their bat0 bridged together, with BLA enabled) Issue: -* BLA backbone nodes receive the frame multiple times on bat0, - once from mesh->bat0 and once from each backbone_gw from LAN +* BLA backbone nodes receive the frame multiple times on bat0 -For unicast, a node will send only to the best backbone gateway -according to the TQ. However for multicast we currently cannot determine -if multiple destination nodes share the same backbone if they don't share -the same backbone with us. So we need to keep sending the unicasts to -all backbone gateways and let the backbone gateways decide which one -will forward the frame. We can use the CLAIM mechanism to make this -decision. +For multicast frames received via batman-adv broadcast packets the +originator of the broadcast packet is checked before decapsulating and +forwarding the frame to bat0 (batadv_bla_is_backbone_gw()-> +batadv_recv_bcast_packet()). If it came from a node which shares the +same BLA backbone with us then it is not forwarded to bat0 to avoid a +loop. -One catch: The batman-adv gateway feature for DHCP packets potentially -sends multicast packets in the same batman-adv unicast header as the -multicast optimizations code. And we are not allowed to drop those even -if we did not claim the source address of the sender, as for such -packets there is only this one multicast-in-unicast packet. +When sending a multicast frame in a non-4-address batman-adv unicast +packet we are currently missing this check - and cannot do so because +the batman-adv unicast packet has no originator address field. -How can we distinguish the two cases? +However, we can simply fix this on the sender side by only sending the +multicast frame via unicasts to interested nodes which do not share the +same BLA backbone with us. This also nicely avoids some unnecessary +transmissions on mesh side. -The gateway feature uses a batman-adv unicast 4 address header. While -the multicast-to-unicasts feature uses a simple, 3 address batman-adv -unicast header. So let's use this to distinguish. +Note that no infinite loop was observed, probably because of dropping +via batadv_interface_tx()->batadv_bla_tx(). However the duplicates still +utterly confuse switches/bridges, ICMPv6 duplicate address detection and +neighbor discovery and therefore leads to long delays before being able +to establish TCP connections, for instance. And it also leads to the Linux +bridge printing messages like: +"br-lan: received packet on eth1 with own address as source address ..." -Fixes: e32470167379 ("batman-adv: check incoming packet type for bla") +Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets") Signed-off-by: Linus Lüssing Acked-by: Simon Wunderlich Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d7665cf8a824c41c61c6e2110ab63d37eb7a8ef7 +Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/3c39a2455a5be02ecceeaf1a15976bddd611392e -diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c -index fe406c17b2c0aa24f49a7d5dee4264fbca56d72f..ffa44d7f7ee5d221e8f511a446eb079a3686844b 100644 ---- a/net/batman-adv/bridge_loop_avoidance.c -+++ b/net/batman-adv/bridge_loop_avoidance.c -@@ -1814,7 +1814,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb, +--- a/net/batman-adv/multicast.c ++++ b/net/batman-adv/multicast.c +@@ -50,6 +50,7 @@ + #include + #include + ++#include "bridge_loop_avoidance.h" + #include "hard-interface.h" + #include "hash.h" + #include "log.h" +@@ -1020,6 +1021,35 @@ batadv_mcast_forw_mode(struct batadv_pri + } + + /** ++ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator ++ * @bat_priv: the bat priv with all the soft interface information ++ * @skb: the multicast packet to send ++ * @vid: the vlan identifier ++ * @orig_node: the originator to send the packet to ++ * ++ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise. ++ */ ++int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, ++ struct sk_buff *skb, ++ unsigned short vid, ++ struct batadv_orig_node *orig_node) ++{ ++ /* Avoid sending multicast-in-unicast packets to other BLA ++ * gateways - they already got the frame from the LAN side ++ * we share with them. ++ * TODO: Refactor to take BLA into account earlier, to avoid ++ * reducing the mcast_fanout count. ++ */ ++ if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) { ++ dev_kfree_skb(skb); ++ return NET_XMIT_SUCCESS; ++ } ++ ++ return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0, ++ orig_node, vid); ++} ++ ++/** + * batadv_mcast_forw_tt() - forwards a packet to multicast listeners * @bat_priv: the bat priv with all the soft interface information - * @skb: the frame to be checked - * @vid: the VLAN ID of the frame -- * @is_bcast: the packet came in a broadcast packet type. -+ * @packet_type: the batman packet type this frame came in - * - * batadv_bla_rx avoidance checks if: - * * we have to race for a claim -@@ -1826,7 +1826,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb, - * further process the skb. - */ - bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, -- unsigned short vid, bool is_bcast) -+ unsigned short vid, int packet_type) - { - struct batadv_bla_backbone_gw *backbone_gw; - struct ethhdr *ethhdr; -@@ -1848,9 +1848,24 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, - goto handled; + * @skb: the multicast packet to transmit +@@ -1056,8 +1086,8 @@ batadv_mcast_forw_tt(struct batadv_priv + break; + } - if (unlikely(atomic_read(&bat_priv->bla.num_requests))) -- /* don't allow broadcasts while requests are in flight */ -- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) -- goto handled; -+ /* don't allow multicast packets while requests are in flight */ -+ if (is_multicast_ether_addr(ethhdr->h_dest)) -+ /* Both broadcast flooding or multicast-via-unicasts -+ * delivery might send to multiple backbone gateways -+ * sharing the same LAN and therefore need to coordinate -+ * which backbone gateway forwards into the LAN, -+ * by claiming the payload source address. -+ * -+ * Broadcast flooding and multicast-via-unicasts -+ * delivery use the following two batman packet types. -+ * Note: explicitly exclude BATADV_UNICAST_4ADDR, -+ * as the DHCP gateway feature will send explicitly -+ * to only one BLA gateway, so the claiming process -+ * should be avoided there. -+ */ -+ if (packet_type == BATADV_BCAST || -+ packet_type == BATADV_UNICAST) -+ goto handled; +- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, +- orig_entry->orig_node, vid); ++ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, ++ orig_entry->orig_node); + } + rcu_read_unlock(); + +@@ -1098,8 +1128,7 @@ batadv_mcast_forw_want_all_ipv4(struct b + break; + } - ether_addr_copy(search_claim.addr, ethhdr->h_source); - search_claim.vid = vid; -@@ -1885,13 +1900,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, - goto allow; +- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, +- orig_node, vid); ++ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); } + rcu_read_unlock(); + return ret; +@@ -1136,8 +1165,7 @@ batadv_mcast_forw_want_all_ipv6(struct b + break; + } -- /* if it is a broadcast ... */ -- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) { -+ /* if it is a multicast ... */ -+ if (is_multicast_ether_addr(ethhdr->h_dest) && -+ (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) { - /* ... drop it. the responsible gateway is in charge. - * -- * We need to check is_bcast because with the gateway -+ * We need to check packet type because with the gateway - * feature, broadcasts (like DHCP requests) may be sent -- * using a unicast packet type. -+ * using a unicast 4 address packet type. See comment above. - */ - goto handled; - } else { -diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h -index 012d72c8d06463d64ed2374b0a9963577a5c25ab..f174ec2525d444f544385ce9f11604544573e67f 100644 ---- a/net/batman-adv/bridge_loop_avoidance.h -+++ b/net/batman-adv/bridge_loop_avoidance.h -@@ -36,7 +36,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac) +- batadv_send_skb_unicast(bat_priv, newskb, BATADV_UNICAST, 0, +- orig_node, vid); ++ batadv_mcast_forw_send_orig(bat_priv, newskb, vid, orig_node); + } + rcu_read_unlock(); + return ret; +--- a/net/batman-adv/multicast.h ++++ b/net/batman-adv/multicast.h +@@ -46,6 +46,11 @@ enum batadv_forw_mode + batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb, + struct batadv_orig_node **mcast_single_orig); - #ifdef CONFIG_BATMAN_ADV_BLA - bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, -- unsigned short vid, bool is_bcast); -+ unsigned short vid, int packet_type); - bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, - unsigned short vid); - bool batadv_bla_is_backbone_gw(struct sk_buff *skb, -@@ -67,7 +67,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr, ++int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, ++ struct sk_buff *skb, ++ unsigned short vid, ++ struct batadv_orig_node *orig_node); ++ + int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, + unsigned short vid); - static inline bool batadv_bla_rx(struct batadv_priv *bat_priv, - struct sk_buff *skb, unsigned short vid, -- bool is_bcast) -+ int packet_type) - { - return false; +@@ -72,6 +77,16 @@ batadv_mcast_forw_mode(struct batadv_pri } -diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c -index 164cc254ef6f621ef7b8fb666821d8997188664f..c99facdbd493e0eb79ee51b1a3212003497e3a32 100644 + + static inline int ++batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv, ++ struct sk_buff *skb, ++ unsigned short vid, ++ struct batadv_orig_node *orig_node) ++{ ++ kfree_skb(skb); ++ return NET_XMIT_DROP; ++} ++ ++static inline int + batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, + unsigned short vid) + { --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c -@@ -423,10 +423,10 @@ void batadv_interface_rx(struct net_device *soft_iface, - struct vlan_ethhdr *vhdr; - struct ethhdr *ethhdr; - unsigned short vid; -- bool is_bcast; -+ int packet_type; - - batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; -- is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); -+ packet_type = batadv_bcast_packet->packet_type; - - skb_pull_rcsum(skb, hdr_size); - skb_reset_mac_header(skb); -@@ -469,7 +469,7 @@ void batadv_interface_rx(struct net_device *soft_iface, - /* Let the bridge loop avoidance check the packet. If will - * not handle it, we can safely push it up. - */ -- if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) -+ if (batadv_bla_rx(bat_priv, skb, vid, packet_type)) - goto out; - - if (orig_node) +@@ -363,9 +363,8 @@ send: + goto dropped; + ret = batadv_send_skb_via_gw(bat_priv, skb, vid); + } else if (mcast_single_orig) { +- ret = batadv_send_skb_unicast(bat_priv, skb, +- BATADV_UNICAST, 0, +- mcast_single_orig, vid); ++ ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid, ++ mcast_single_orig); + } else if (forw_mode == BATADV_FORW_SOME) { + ret = batadv_mcast_forw_send(bat_priv, skb, vid); + } else { diff --git a/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch b/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch deleted file mode 100644 index bf936a8..0000000 --- a/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch +++ /dev/null @@ -1,190 +0,0 @@ -From: Linus Lüssing -Date: Tue, 15 Sep 2020 09:54:10 +0200 -Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh - -Scenario: -* Multicast frame send from BLA backbone gateways (multiple nodes - with their bat0 bridged together, with BLA enabled) sharing the same - LAN to nodes in the mesh - -Issue: -* Nodes receive the frame multiple times on bat0 from the mesh, - once from each foreign BLA backbone gateway which shares the same LAN - with another - -For multicast frames via batman-adv broadcast packets coming from the -same BLA backbone but from different backbone gateways duplicates are -currently detected via a CRC history of previously received packets. - -However this CRC so far was not performed for multicast frames received -via batman-adv unicast packets. Fixing this by appyling the same check -for such packets, too. - -Room for improvements in the future: Ideally we would introduce the -possibility to not only claim a client, but a complete originator, too. -This would allow us to only send a multicast-in-unicast packet from a BLA -backbone gateway claiming the node and by that avoid potential redundant -transmissions in the first place. - -Fixes: e5cf86d30a9b ("batman-adv: add broadcast duplicate check") -Signed-off-by: Linus Lüssing -Signed-off-by: Sven Eckelmann - -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c5cb6a670cc3070d9d5c5562f95fa75faac767ba - -diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c -index ffa44d7f7ee5d221e8f511a446eb079a3686844b..a6b26ca5c6973f230284eaa55ad80808593e796b 100644 ---- a/net/batman-adv/bridge_loop_avoidance.c -+++ b/net/batman-adv/bridge_loop_avoidance.c -@@ -1581,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv) - } - - /** -- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup. -+ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup. - * @bat_priv: the bat priv with all the soft interface information -- * @skb: contains the bcast_packet to be checked -+ * @skb: contains the multicast packet to be checked -+ * @payload_ptr: pointer to position inside the head buffer of the skb -+ * marking the start of the data to be CRC'ed -+ * @orig: originator mac address, NULL if unknown - * -- * check if it is on our broadcast list. Another gateway might -- * have sent the same packet because it is connected to the same backbone, -- * so we have to remove this duplicate. -+ * Check if it is on our broadcast list. Another gateway might have sent the -+ * same packet because it is connected to the same backbone, so we have to -+ * remove this duplicate. - * - * This is performed by checking the CRC, which will tell us - * with a good chance that it is the same packet. If it is furthermore -@@ -1596,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv) - * - * Return: true if a packet is in the duplicate list, false otherwise. - */ --bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, -- struct sk_buff *skb) -+static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv, -+ struct sk_buff *skb, u8 *payload_ptr, -+ const u8 *orig) - { -- int i, curr; -- __be32 crc; -- struct batadv_bcast_packet *bcast_packet; - struct batadv_bcast_duplist_entry *entry; - bool ret = false; -- -- bcast_packet = (struct batadv_bcast_packet *)skb->data; -+ int i, curr; -+ __be32 crc; - - /* calculate the crc ... */ -- crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1)); -+ crc = batadv_skb_crc32(skb, payload_ptr); - - spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); - -@@ -1627,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, - if (entry->crc != crc) - continue; - -- if (batadv_compare_eth(entry->orig, bcast_packet->orig)) -- continue; -+ /* are the originators both known and not anonymous? */ -+ if (orig && !is_zero_ether_addr(orig) && -+ !is_zero_ether_addr(entry->orig)) { -+ /* If known, check if the new frame came from -+ * the same originator: -+ * We are safe to take identical frames from the -+ * same orig, if known, as multiplications in -+ * the mesh are detected via the (orig, seqno) pair. -+ * So we can be a bit more liberal here and allow -+ * identical frames from the same orig which the source -+ * host might have sent multiple times on purpose. -+ */ -+ if (batadv_compare_eth(entry->orig, orig)) -+ continue; -+ } - - /* this entry seems to match: same crc, not too old, - * and from another gw. therefore return true to forbid it. -@@ -1644,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, - entry = &bat_priv->bla.bcast_duplist[curr]; - entry->crc = crc; - entry->entrytime = jiffies; -- ether_addr_copy(entry->orig, bcast_packet->orig); -+ -+ /* known originator */ -+ if (orig) -+ ether_addr_copy(entry->orig, orig); -+ /* anonymous originator */ -+ else -+ eth_zero_addr(entry->orig); -+ - bat_priv->bla.bcast_duplist_curr = curr; - - out: -@@ -1653,6 +1674,48 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, - return ret; - } - -+/** -+ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup. -+ * @bat_priv: the bat priv with all the soft interface information -+ * @skb: contains the multicast packet to be checked, decapsulated from a -+ * unicast_packet -+ * -+ * Check if it is on our broadcast list. Another gateway might have sent the -+ * same packet because it is connected to the same backbone, so we have to -+ * remove this duplicate. -+ * -+ * Return: true if a packet is in the duplicate list, false otherwise. -+ */ -+static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv, -+ struct sk_buff *skb) -+{ -+ return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL); -+} -+ -+/** -+ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup. -+ * @bat_priv: the bat priv with all the soft interface information -+ * @skb: contains the bcast_packet to be checked -+ * -+ * Check if it is on our broadcast list. Another gateway might have sent the -+ * same packet because it is connected to the same backbone, so we have to -+ * remove this duplicate. -+ * -+ * Return: true if a packet is in the duplicate list, false otherwise. -+ */ -+bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, -+ struct sk_buff *skb) -+{ -+ struct batadv_bcast_packet *bcast_packet; -+ u8 *payload_ptr; -+ -+ bcast_packet = (struct batadv_bcast_packet *)skb->data; -+ payload_ptr = (u8 *)(bcast_packet + 1); -+ -+ return batadv_bla_check_duplist(bat_priv, skb, payload_ptr, -+ bcast_packet->orig); -+} -+ - /** - * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for - * the VLAN identified by vid. -@@ -1867,6 +1930,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, - packet_type == BATADV_UNICAST) - goto handled; - -+ /* potential duplicates from foreign BLA backbone gateways via -+ * multicast-in-unicast packets -+ */ -+ if (is_multicast_ether_addr(ethhdr->h_dest) && -+ packet_type == BATADV_UNICAST && -+ batadv_bla_check_ucast_duplist(bat_priv, skb)) -+ goto handled; -+ - ether_addr_copy(search_claim.addr, ethhdr->h_source); - search_claim.vid = vid; - claim = batadv_claim_hash_find(bat_priv, &search_claim); diff --git a/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch b/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch new file mode 100644 index 0000000..23d2a1e --- /dev/null +++ b/batman-adv/patches/0029-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch @@ -0,0 +1,150 @@ +From: Linus Lüssing +Date: Tue, 15 Sep 2020 09:54:09 +0200 +Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh + +Scenario: +* Multicast frame send from mesh to a BLA backbone (multiple nodes + with their bat0 bridged together, with BLA enabled) + +Issue: +* BLA backbone nodes receive the frame multiple times on bat0, + once from mesh->bat0 and once from each backbone_gw from LAN + +For unicast, a node will send only to the best backbone gateway +according to the TQ. However for multicast we currently cannot determine +if multiple destination nodes share the same backbone if they don't share +the same backbone with us. So we need to keep sending the unicasts to +all backbone gateways and let the backbone gateways decide which one +will forward the frame. We can use the CLAIM mechanism to make this +decision. + +One catch: The batman-adv gateway feature for DHCP packets potentially +sends multicast packets in the same batman-adv unicast header as the +multicast optimizations code. And we are not allowed to drop those even +if we did not claim the source address of the sender, as for such +packets there is only this one multicast-in-unicast packet. + +How can we distinguish the two cases? + +The gateway feature uses a batman-adv unicast 4 address header. While +the multicast-to-unicasts feature uses a simple, 3 address batman-adv +unicast header. So let's use this to distinguish. + +Fixes: e32470167379 ("batman-adv: check incoming packet type for bla") +Signed-off-by: Linus Lüssing +Acked-by: Simon Wunderlich +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d7665cf8a824c41c61c6e2110ab63d37eb7a8ef7 + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -1814,7 +1814,7 @@ batadv_bla_loopdetect_check(struct batad + * @bat_priv: the bat priv with all the soft interface information + * @skb: the frame to be checked + * @vid: the VLAN ID of the frame +- * @is_bcast: the packet came in a broadcast packet type. ++ * @packet_type: the batman packet type this frame came in + * + * batadv_bla_rx avoidance checks if: + * * we have to race for a claim +@@ -1826,7 +1826,7 @@ batadv_bla_loopdetect_check(struct batad + * further process the skb. + */ + bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, +- unsigned short vid, bool is_bcast) ++ unsigned short vid, int packet_type) + { + struct batadv_bla_backbone_gw *backbone_gw; + struct ethhdr *ethhdr; +@@ -1848,9 +1848,24 @@ bool batadv_bla_rx(struct batadv_priv *b + goto handled; + + if (unlikely(atomic_read(&bat_priv->bla.num_requests))) +- /* don't allow broadcasts while requests are in flight */ +- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) +- goto handled; ++ /* don't allow multicast packets while requests are in flight */ ++ if (is_multicast_ether_addr(ethhdr->h_dest)) ++ /* Both broadcast flooding or multicast-via-unicasts ++ * delivery might send to multiple backbone gateways ++ * sharing the same LAN and therefore need to coordinate ++ * which backbone gateway forwards into the LAN, ++ * by claiming the payload source address. ++ * ++ * Broadcast flooding and multicast-via-unicasts ++ * delivery use the following two batman packet types. ++ * Note: explicitly exclude BATADV_UNICAST_4ADDR, ++ * as the DHCP gateway feature will send explicitly ++ * to only one BLA gateway, so the claiming process ++ * should be avoided there. ++ */ ++ if (packet_type == BATADV_BCAST || ++ packet_type == BATADV_UNICAST) ++ goto handled; + + ether_addr_copy(search_claim.addr, ethhdr->h_source); + search_claim.vid = vid; +@@ -1885,13 +1900,14 @@ bool batadv_bla_rx(struct batadv_priv *b + goto allow; + } + +- /* if it is a broadcast ... */ +- if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) { ++ /* if it is a multicast ... */ ++ if (is_multicast_ether_addr(ethhdr->h_dest) && ++ (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) { + /* ... drop it. the responsible gateway is in charge. + * +- * We need to check is_bcast because with the gateway ++ * We need to check packet type because with the gateway + * feature, broadcasts (like DHCP requests) may be sent +- * using a unicast packet type. ++ * using a unicast 4 address packet type. See comment above. + */ + goto handled; + } else { +--- a/net/batman-adv/bridge_loop_avoidance.h ++++ b/net/batman-adv/bridge_loop_avoidance.h +@@ -36,7 +36,7 @@ static inline bool batadv_bla_is_loopdet + + #ifdef CONFIG_BATMAN_ADV_BLA + bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, +- unsigned short vid, bool is_bcast); ++ unsigned short vid, int packet_type); + bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, + unsigned short vid); + bool batadv_bla_is_backbone_gw(struct sk_buff *skb, +@@ -67,7 +67,7 @@ bool batadv_bla_check_claim(struct batad + + static inline bool batadv_bla_rx(struct batadv_priv *bat_priv, + struct sk_buff *skb, unsigned short vid, +- bool is_bcast) ++ int packet_type) + { + return false; + } +--- a/net/batman-adv/soft-interface.c ++++ b/net/batman-adv/soft-interface.c +@@ -423,10 +423,10 @@ void batadv_interface_rx(struct net_devi + struct vlan_ethhdr *vhdr; + struct ethhdr *ethhdr; + unsigned short vid; +- bool is_bcast; ++ int packet_type; + + batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; +- is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST); ++ packet_type = batadv_bcast_packet->packet_type; + + skb_pull_rcsum(skb, hdr_size); + skb_reset_mac_header(skb); +@@ -469,7 +469,7 @@ void batadv_interface_rx(struct net_devi + /* Let the bridge loop avoidance check the packet. If will + * not handle it, we can safely push it up. + */ +- if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) ++ if (batadv_bla_rx(bat_priv, skb, vid, packet_type)) + goto out; + + if (orig_node) diff --git a/batman-adv/patches/0030-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch b/batman-adv/patches/0030-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch new file mode 100644 index 0000000..1ab3677 --- /dev/null +++ b/batman-adv/patches/0030-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch @@ -0,0 +1,189 @@ +From: Linus Lüssing +Date: Tue, 15 Sep 2020 09:54:10 +0200 +Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh + +Scenario: +* Multicast frame send from BLA backbone gateways (multiple nodes + with their bat0 bridged together, with BLA enabled) sharing the same + LAN to nodes in the mesh + +Issue: +* Nodes receive the frame multiple times on bat0 from the mesh, + once from each foreign BLA backbone gateway which shares the same LAN + with another + +For multicast frames via batman-adv broadcast packets coming from the +same BLA backbone but from different backbone gateways duplicates are +currently detected via a CRC history of previously received packets. + +However this CRC so far was not performed for multicast frames received +via batman-adv unicast packets. Fixing this by appyling the same check +for such packets, too. + +Room for improvements in the future: Ideally we would introduce the +possibility to not only claim a client, but a complete originator, too. +This would allow us to only send a multicast-in-unicast packet from a BLA +backbone gateway claiming the node and by that avoid potential redundant +transmissions in the first place. + +Fixes: e5cf86d30a9b ("batman-adv: add broadcast duplicate check") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c5cb6a670cc3070d9d5c5562f95fa75faac767ba + +--- a/net/batman-adv/bridge_loop_avoidance.c ++++ b/net/batman-adv/bridge_loop_avoidance.c +@@ -1581,13 +1581,16 @@ int batadv_bla_init(struct batadv_priv * + } + + /** +- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup. ++ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup. + * @bat_priv: the bat priv with all the soft interface information +- * @skb: contains the bcast_packet to be checked +- * +- * check if it is on our broadcast list. Another gateway might +- * have sent the same packet because it is connected to the same backbone, +- * so we have to remove this duplicate. ++ * @skb: contains the multicast packet to be checked ++ * @payload_ptr: pointer to position inside the head buffer of the skb ++ * marking the start of the data to be CRC'ed ++ * @orig: originator mac address, NULL if unknown ++ * ++ * Check if it is on our broadcast list. Another gateway might have sent the ++ * same packet because it is connected to the same backbone, so we have to ++ * remove this duplicate. + * + * This is performed by checking the CRC, which will tell us + * with a good chance that it is the same packet. If it is furthermore +@@ -1596,19 +1599,17 @@ int batadv_bla_init(struct batadv_priv * + * + * Return: true if a packet is in the duplicate list, false otherwise. + */ +-bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, +- struct sk_buff *skb) ++static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv, ++ struct sk_buff *skb, u8 *payload_ptr, ++ const u8 *orig) + { +- int i, curr; +- __be32 crc; +- struct batadv_bcast_packet *bcast_packet; + struct batadv_bcast_duplist_entry *entry; + bool ret = false; +- +- bcast_packet = (struct batadv_bcast_packet *)skb->data; ++ int i, curr; ++ __be32 crc; + + /* calculate the crc ... */ +- crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1)); ++ crc = batadv_skb_crc32(skb, payload_ptr); + + spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); + +@@ -1627,8 +1628,21 @@ bool batadv_bla_check_bcast_duplist(stru + if (entry->crc != crc) + continue; + +- if (batadv_compare_eth(entry->orig, bcast_packet->orig)) +- continue; ++ /* are the originators both known and not anonymous? */ ++ if (orig && !is_zero_ether_addr(orig) && ++ !is_zero_ether_addr(entry->orig)) { ++ /* If known, check if the new frame came from ++ * the same originator: ++ * We are safe to take identical frames from the ++ * same orig, if known, as multiplications in ++ * the mesh are detected via the (orig, seqno) pair. ++ * So we can be a bit more liberal here and allow ++ * identical frames from the same orig which the source ++ * host might have sent multiple times on purpose. ++ */ ++ if (batadv_compare_eth(entry->orig, orig)) ++ continue; ++ } + + /* this entry seems to match: same crc, not too old, + * and from another gw. therefore return true to forbid it. +@@ -1644,7 +1658,14 @@ bool batadv_bla_check_bcast_duplist(stru + entry = &bat_priv->bla.bcast_duplist[curr]; + entry->crc = crc; + entry->entrytime = jiffies; +- ether_addr_copy(entry->orig, bcast_packet->orig); ++ ++ /* known originator */ ++ if (orig) ++ ether_addr_copy(entry->orig, orig); ++ /* anonymous originator */ ++ else ++ eth_zero_addr(entry->orig); ++ + bat_priv->bla.bcast_duplist_curr = curr; + + out: +@@ -1654,6 +1675,48 @@ out: + } + + /** ++ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup. ++ * @bat_priv: the bat priv with all the soft interface information ++ * @skb: contains the multicast packet to be checked, decapsulated from a ++ * unicast_packet ++ * ++ * Check if it is on our broadcast list. Another gateway might have sent the ++ * same packet because it is connected to the same backbone, so we have to ++ * remove this duplicate. ++ * ++ * Return: true if a packet is in the duplicate list, false otherwise. ++ */ ++static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv, ++ struct sk_buff *skb) ++{ ++ return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL); ++} ++ ++/** ++ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup. ++ * @bat_priv: the bat priv with all the soft interface information ++ * @skb: contains the bcast_packet to be checked ++ * ++ * Check if it is on our broadcast list. Another gateway might have sent the ++ * same packet because it is connected to the same backbone, so we have to ++ * remove this duplicate. ++ * ++ * Return: true if a packet is in the duplicate list, false otherwise. ++ */ ++bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, ++ struct sk_buff *skb) ++{ ++ struct batadv_bcast_packet *bcast_packet; ++ u8 *payload_ptr; ++ ++ bcast_packet = (struct batadv_bcast_packet *)skb->data; ++ payload_ptr = (u8 *)(bcast_packet + 1); ++ ++ return batadv_bla_check_duplist(bat_priv, skb, payload_ptr, ++ bcast_packet->orig); ++} ++ ++/** + * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for + * the VLAN identified by vid. + * @bat_priv: the bat priv with all the soft interface information +@@ -1867,6 +1930,14 @@ bool batadv_bla_rx(struct batadv_priv *b + packet_type == BATADV_UNICAST) + goto handled; + ++ /* potential duplicates from foreign BLA backbone gateways via ++ * multicast-in-unicast packets ++ */ ++ if (is_multicast_ether_addr(ethhdr->h_dest) && ++ packet_type == BATADV_UNICAST && ++ batadv_bla_check_ucast_duplist(bat_priv, skb)) ++ goto handled; ++ + ether_addr_copy(search_claim.addr, ethhdr->h_source); + search_claim.vid = vid; + claim = batadv_claim_hash_find(bat_priv, &search_claim); diff --git a/batman-adv/patches/0030-batman-adv-set-.owner-to-THIS_MODULE.patch b/batman-adv/patches/0030-batman-adv-set-.owner-to-THIS_MODULE.patch deleted file mode 100644 index b603332..0000000 --- a/batman-adv/patches/0030-batman-adv-set-.owner-to-THIS_MODULE.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Taehee Yoo -Date: Sun, 15 Nov 2020 10:30:04 +0000 -Subject: batman-adv: set .owner to THIS_MODULE - -If THIS_MODULE is not set, the module would be removed while debugfs is -being used. -It eventually makes kernel panic. - -Fixes: 24571be14371 ("batman-adv: add routing debug log accessible via debugfs") -Signed-off-by: Taehee Yoo -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e2937539a2c9f8a8536515258bc1f08bed19a06 - -diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c -index 60ce11e16a905e790424a2d7aca81c1f945c1ec2..a51fadeaefb58e75a84820998390acd3759ef3a8 100644 ---- a/net/batman-adv/log.c -+++ b/net/batman-adv/log.c -@@ -180,6 +180,7 @@ static const struct file_operations batadv_log_fops = { - .read = batadv_log_read, - .poll = batadv_log_poll, - .llseek = no_llseek, -+ .owner = THIS_MODULE, - }; - - /** diff --git a/batman-adv/patches/0031-batman-adv-Consider-fragmentation-for-needed_headroo.patch b/batman-adv/patches/0031-batman-adv-Consider-fragmentation-for-needed_headroo.patch deleted file mode 100644 index 7ce5090..0000000 --- a/batman-adv/patches/0031-batman-adv-Consider-fragmentation-for-needed_headroo.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Sven Eckelmann -Date: Thu, 26 Nov 2020 18:15:06 +0100 -Subject: batman-adv: Consider fragmentation for needed_headroom - -If a batman-adv packets has to be fragmented, then the original batman-adv -packet header is not stripped away. Instead, only a new header is added in -front of the packet after it was split. - -This size must be considered to avoid cost intensive reallocations during -the transmission through the various device layers. - -Fixes: e2b4301f4e2d ("batman-adv: Add lower layer needed_(head|tail)room to own ones") -Reported-by: Linus Lüssing -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/92064deda9b063ca2d5a53b307c6127a9453357c - -diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -index 62b926dd4aaeffd82da83654c8e568de2c3714fb..e0f70ae28df4e2fb0a7972a1ca9d5fcc986c0d6c 100644 ---- a/net/batman-adv/hard-interface.c -+++ b/net/batman-adv/hard-interface.c -@@ -553,6 +553,9 @@ static void batadv_hardif_recalc_extra_skbroom(struct net_device *soft_iface) - needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN); - needed_headroom += batadv_max_header_len(); - -+ /* fragmentation headers don't strip the unicast/... header */ -+ needed_headroom += sizeof(struct batadv_frag_packet); -+ - soft_iface->needed_headroom = needed_headroom; - soft_iface->needed_tailroom = lower_tailroom; - } diff --git a/batman-adv/patches/0031-batman-adv-set-.owner-to-THIS_MODULE.patch b/batman-adv/patches/0031-batman-adv-set-.owner-to-THIS_MODULE.patch new file mode 100644 index 0000000..73e0a6a --- /dev/null +++ b/batman-adv/patches/0031-batman-adv-set-.owner-to-THIS_MODULE.patch @@ -0,0 +1,23 @@ +From: Taehee Yoo +Date: Sun, 15 Nov 2020 10:30:04 +0000 +Subject: batman-adv: set .owner to THIS_MODULE + +If THIS_MODULE is not set, the module would be removed while debugfs is +being used. +It eventually makes kernel panic. + +Fixes: 24571be14371 ("batman-adv: add routing debug log accessible via debugfs") +Signed-off-by: Taehee Yoo +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6e2937539a2c9f8a8536515258bc1f08bed19a06 + +--- a/net/batman-adv/log.c ++++ b/net/batman-adv/log.c +@@ -180,6 +180,7 @@ static const struct file_operations bata + .read = batadv_log_read, + .poll = batadv_log_poll, + .llseek = no_llseek, ++ .owner = THIS_MODULE, + }; + + /** diff --git a/batman-adv/patches/0032-batman-adv-Consider-fragmentation-for-needed_headroo.patch b/batman-adv/patches/0032-batman-adv-Consider-fragmentation-for-needed_headroo.patch new file mode 100644 index 0000000..1bd442f --- /dev/null +++ b/batman-adv/patches/0032-batman-adv-Consider-fragmentation-for-needed_headroo.patch @@ -0,0 +1,28 @@ +From: Sven Eckelmann +Date: Thu, 26 Nov 2020 18:15:06 +0100 +Subject: batman-adv: Consider fragmentation for needed_headroom + +If a batman-adv packets has to be fragmented, then the original batman-adv +packet header is not stripped away. Instead, only a new header is added in +front of the packet after it was split. + +This size must be considered to avoid cost intensive reallocations during +the transmission through the various device layers. + +Fixes: e2b4301f4e2d ("batman-adv: Add lower layer needed_(head|tail)room to own ones") +Reported-by: Linus Lüssing +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/92064deda9b063ca2d5a53b307c6127a9453357c + +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -553,6 +553,9 @@ static void batadv_hardif_recalc_extra_s + needed_headroom = lower_headroom + (lower_header_len - ETH_HLEN); + needed_headroom += batadv_max_header_len(); + ++ /* fragmentation headers don't strip the unicast/... header */ ++ needed_headroom += sizeof(struct batadv_frag_packet); ++ + soft_iface->needed_headroom = needed_headroom; + soft_iface->needed_tailroom = lower_tailroom; + } diff --git a/batman-adv/patches/0032-batman-adv-Reserve-needed_-room-for-fragments.patch b/batman-adv/patches/0032-batman-adv-Reserve-needed_-room-for-fragments.patch deleted file mode 100644 index 0ad2b0c..0000000 --- a/batman-adv/patches/0032-batman-adv-Reserve-needed_-room-for-fragments.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Sven Eckelmann -Date: Wed, 25 Nov 2020 13:16:43 +0100 -Subject: batman-adv: Reserve needed_*room for fragments - -The batadv net_device is trying to propagate the needed_headroom and -needed_tailroom from the lower devices. This is needed to avoid cost -intensive reallocations using pskb_expand_head during the transmission. - -But the fragmentation code split the skb's without adding extra room at the -end/beginning of the various fragments. This reduced the performance of -transmissions over complex scenarios (batadv on vxlan on wireguard) because -the lower devices had to perform the reallocations at least once. - -Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0966d5424bb87e863037301488519ccdd69e4d26 - -diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c -index 385fccdcf69d05d63f59d024dfb721b1e8f1c8b9..f1d202ff396cd69949915a9e90e763f3a68255b7 100644 ---- a/net/batman-adv/fragmentation.c -+++ b/net/batman-adv/fragmentation.c -@@ -391,6 +391,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, - - /** - * batadv_frag_create() - create a fragment from skb -+ * @net_dev: outgoing device for fragment - * @skb: skb to create fragment from - * @frag_head: header to use in new fragment - * @fragment_size: size of new fragment -@@ -401,22 +402,25 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb, - * - * Return: the new fragment, NULL on error. - */ --static struct sk_buff *batadv_frag_create(struct sk_buff *skb, -+static struct sk_buff *batadv_frag_create(struct net_device *net_dev, -+ struct sk_buff *skb, - struct batadv_frag_packet *frag_head, - unsigned int fragment_size) - { -+ unsigned int ll_reserved = LL_RESERVED_SPACE(net_dev); -+ unsigned int tailroom = net_dev->needed_tailroom; - struct sk_buff *skb_fragment; - unsigned int header_size = sizeof(*frag_head); - unsigned int mtu = fragment_size + header_size; - -- skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); -+ skb_fragment = dev_alloc_skb(ll_reserved + mtu + tailroom); - if (!skb_fragment) - goto err; - - skb_fragment->priority = skb->priority; - - /* Eat the last mtu-bytes of the skb */ -- skb_reserve(skb_fragment, header_size + ETH_HLEN); -+ skb_reserve(skb_fragment, ll_reserved + header_size); - skb_split(skb, skb_fragment, skb->len - fragment_size); - - /* Add the header */ -@@ -439,11 +443,12 @@ int batadv_frag_send_packet(struct sk_buff *skb, - struct batadv_orig_node *orig_node, - struct batadv_neigh_node *neigh_node) - { -+ struct net_device *net_dev = neigh_node->if_incoming->net_dev; - struct batadv_priv *bat_priv; - struct batadv_hard_iface *primary_if = NULL; - struct batadv_frag_packet frag_header; - struct sk_buff *skb_fragment; -- unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; -+ unsigned int mtu = net_dev->mtu; - unsigned int header_size = sizeof(frag_header); - unsigned int max_fragment_size, num_fragments; - int ret; -@@ -503,7 +508,7 @@ int batadv_frag_send_packet(struct sk_buff *skb, - goto put_primary_if; - } - -- skb_fragment = batadv_frag_create(skb, &frag_header, -+ skb_fragment = batadv_frag_create(net_dev, skb, &frag_header, - max_fragment_size); - if (!skb_fragment) { - ret = -ENOMEM; diff --git a/batman-adv/patches/0033-batman-adv-Don-t-always-reallocate-the-fragmentation.patch b/batman-adv/patches/0033-batman-adv-Don-t-always-reallocate-the-fragmentation.patch deleted file mode 100644 index 00bc3f2..0000000 --- a/batman-adv/patches/0033-batman-adv-Don-t-always-reallocate-the-fragmentation.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Sven Eckelmann -Date: Thu, 26 Nov 2020 18:24:49 +0100 -Subject: batman-adv: Don't always reallocate the fragmentation skb head - -When a packet is fragmented by batman-adv, the original batman-adv header -is not modified. Only a new fragmentation is inserted between the original -one and the ethernet header. The code must therefore make sure that it has -a writable region of this size in the skbuff head. - -But it is not useful to always reallocate the skbuff by this size even when -there would be more than enough headroom still in the skb. The reallocation -is just to costly during in this codepath. - -Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") -Signed-off-by: Sven Eckelmann -Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3e3ff987876d3be70d928561acbefe5a48ab1654 - -diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c -index f1d202ff396cd69949915a9e90e763f3a68255b7..0da90e73c79bffe86072f0d704f0777d76b35f4c 100644 ---- a/net/batman-adv/fragmentation.c -+++ b/net/batman-adv/fragmentation.c -@@ -527,13 +527,14 @@ int batadv_frag_send_packet(struct sk_buff *skb, - frag_header.no++; - } - -- /* Make room for the fragment header. */ -- if (batadv_skb_head_push(skb, header_size) < 0 || -- pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0) { -- ret = -ENOMEM; -+ /* make sure that there is at least enough head for the fragmentation -+ * and ethernet headers -+ */ -+ ret = skb_cow_head(skb, ETH_HLEN + header_size); -+ if (ret < 0) - goto put_primary_if; -- } - -+ skb_push(skb, header_size); - memcpy(skb->data, &frag_header, header_size); - - /* Send the last fragment */ diff --git a/batman-adv/patches/0033-batman-adv-Reserve-needed_-room-for-fragments.patch b/batman-adv/patches/0033-batman-adv-Reserve-needed_-room-for-fragments.patch new file mode 100644 index 0000000..1213782 --- /dev/null +++ b/batman-adv/patches/0033-batman-adv-Reserve-needed_-room-for-fragments.patch @@ -0,0 +1,79 @@ +From: Sven Eckelmann +Date: Wed, 25 Nov 2020 13:16:43 +0100 +Subject: batman-adv: Reserve needed_*room for fragments + +The batadv net_device is trying to propagate the needed_headroom and +needed_tailroom from the lower devices. This is needed to avoid cost +intensive reallocations using pskb_expand_head during the transmission. + +But the fragmentation code split the skb's without adding extra room at the +end/beginning of the various fragments. This reduced the performance of +transmissions over complex scenarios (batadv on vxlan on wireguard) because +the lower devices had to perform the reallocations at least once. + +Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0966d5424bb87e863037301488519ccdd69e4d26 + +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -391,6 +391,7 @@ out: + + /** + * batadv_frag_create() - create a fragment from skb ++ * @net_dev: outgoing device for fragment + * @skb: skb to create fragment from + * @frag_head: header to use in new fragment + * @fragment_size: size of new fragment +@@ -401,22 +402,25 @@ out: + * + * Return: the new fragment, NULL on error. + */ +-static struct sk_buff *batadv_frag_create(struct sk_buff *skb, ++static struct sk_buff *batadv_frag_create(struct net_device *net_dev, ++ struct sk_buff *skb, + struct batadv_frag_packet *frag_head, + unsigned int fragment_size) + { ++ unsigned int ll_reserved = LL_RESERVED_SPACE(net_dev); ++ unsigned int tailroom = net_dev->needed_tailroom; + struct sk_buff *skb_fragment; + unsigned int header_size = sizeof(*frag_head); + unsigned int mtu = fragment_size + header_size; + +- skb_fragment = netdev_alloc_skb(NULL, mtu + ETH_HLEN); ++ skb_fragment = dev_alloc_skb(ll_reserved + mtu + tailroom); + if (!skb_fragment) + goto err; + + skb_fragment->priority = skb->priority; + + /* Eat the last mtu-bytes of the skb */ +- skb_reserve(skb_fragment, header_size + ETH_HLEN); ++ skb_reserve(skb_fragment, ll_reserved + header_size); + skb_split(skb, skb_fragment, skb->len - fragment_size); + + /* Add the header */ +@@ -439,11 +443,12 @@ int batadv_frag_send_packet(struct sk_bu + struct batadv_orig_node *orig_node, + struct batadv_neigh_node *neigh_node) + { ++ struct net_device *net_dev = neigh_node->if_incoming->net_dev; + struct batadv_priv *bat_priv; + struct batadv_hard_iface *primary_if = NULL; + struct batadv_frag_packet frag_header; + struct sk_buff *skb_fragment; +- unsigned int mtu = neigh_node->if_incoming->net_dev->mtu; ++ unsigned int mtu = net_dev->mtu; + unsigned int header_size = sizeof(frag_header); + unsigned int max_fragment_size, num_fragments; + int ret; +@@ -503,7 +508,7 @@ int batadv_frag_send_packet(struct sk_bu + goto put_primary_if; + } + +- skb_fragment = batadv_frag_create(skb, &frag_header, ++ skb_fragment = batadv_frag_create(net_dev, skb, &frag_header, + max_fragment_size); + if (!skb_fragment) { + ret = -ENOMEM; diff --git a/batman-adv/patches/0034-batman-adv-Don-t-always-reallocate-the-fragmentation.patch b/batman-adv/patches/0034-batman-adv-Don-t-always-reallocate-the-fragmentation.patch new file mode 100644 index 0000000..19dde12 --- /dev/null +++ b/batman-adv/patches/0034-batman-adv-Don-t-always-reallocate-the-fragmentation.patch @@ -0,0 +1,39 @@ +From: Sven Eckelmann +Date: Thu, 26 Nov 2020 18:24:49 +0100 +Subject: batman-adv: Don't always reallocate the fragmentation skb head + +When a packet is fragmented by batman-adv, the original batman-adv header +is not modified. Only a new fragmentation is inserted between the original +one and the ethernet header. The code must therefore make sure that it has +a writable region of this size in the skbuff head. + +But it is not useful to always reallocate the skbuff by this size even when +there would be more than enough headroom still in the skb. The reallocation +is just to costly during in this codepath. + +Fixes: db56e4ecf5c2 ("batman-adv: Fragment and send skbs larger than mtu") +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3e3ff987876d3be70d928561acbefe5a48ab1654 + +--- a/net/batman-adv/fragmentation.c ++++ b/net/batman-adv/fragmentation.c +@@ -527,13 +527,14 @@ int batadv_frag_send_packet(struct sk_bu + frag_header.no++; + } + +- /* Make room for the fragment header. */ +- if (batadv_skb_head_push(skb, header_size) < 0 || +- pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0) { +- ret = -ENOMEM; ++ /* make sure that there is at least enough head for the fragmentation ++ * and ethernet headers ++ */ ++ ret = skb_cow_head(skb, ETH_HLEN + header_size); ++ if (ret < 0) + goto put_primary_if; +- } + ++ skb_push(skb, header_size); + memcpy(skb->data, &frag_header, header_size); + + /* Send the last fragment */ diff --git a/batman-adv/patches/0035-batman-adv-Avoid-WARN_ON-timing-related-checks.patch b/batman-adv/patches/0035-batman-adv-Avoid-WARN_ON-timing-related-checks.patch new file mode 100644 index 0000000..0fcb9ec --- /dev/null +++ b/batman-adv/patches/0035-batman-adv-Avoid-WARN_ON-timing-related-checks.patch @@ -0,0 +1,31 @@ +From: Sven Eckelmann +Date: Tue, 18 May 2021 21:00:27 +0200 +Subject: batman-adv: Avoid WARN_ON timing related checks + +The soft/batadv interface for a queued OGM can be changed during the time +the OGM was queued for transmission and when the OGM is actually +transmitted by the worker. + +But WARN_ON must be used to denote kernel bugs and not to print simple +warnings. A warning can simply be printed using pr_warn. + +Reported-by: Tetsuo Handa +Reported-by: syzbot+c0b807de416427ff3dd1@syzkaller.appspotmail.com +Fixes: 29b9256e6631 ("batman-adv: consider outgoing interface in OGM sending") +Signed-off-by: Sven Eckelmann +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/5061f9c502d7101912089d8f4a7866e0a926a49a + +--- a/net/batman-adv/bat_iv_ogm.c ++++ b/net/batman-adv/bat_iv_ogm.c +@@ -409,8 +409,10 @@ static void batadv_iv_ogm_emit(struct ba + if (WARN_ON(!forw_packet->if_outgoing)) + return; + +- if (WARN_ON(forw_packet->if_outgoing->soft_iface != soft_iface)) ++ if (forw_packet->if_outgoing->soft_iface != soft_iface) { ++ pr_warn("%s: soft interface switch for queued OGM\n", __func__); + return; ++ } + + if (forw_packet->if_incoming->if_status != BATADV_IF_ACTIVE) + return;